Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I write a single class to compile multiple times with different number types?

I'm trying to write classes which handle different number types. I know that C# (and .Net in general, I believe) has no INumber interface, so I cannot use something like the following:

    public class Adder<T> where T:INumber
    {
        public T Add(T a, T b)
        {
            return a + b;
        }
    }

That's okay, though, because I'd like to avoid the boxing/unboxing of every one of my numbers. I could, however, use conditional compilation for each type I want to support:

#if FLOAT 
    public class AdderF
    {
        public float Add(float a, float b)
#else
    public class Adder
    {
        public int Add(int a, int b)
#endif
        {
            return a + b;
        }
    }

This means I'll need to compile a different Library.dll and LibraryF.dll, however. Is there any more elegant solution to this?

Obviously, in my example, I can simply write the code twice. I would like to use this process, however, to create large complicated data structures with an integer version and floating-point version, so do not want the possibility of copy-paste errors when updating my structure. Nor do I want the speed loss from wrapping the floating-point structure in an integral-wrapper, and unnecessarily converting all inputs to the more lenient data type.

like image 825
dlras2 Avatar asked Jul 01 '11 15:07

dlras2


3 Answers

I guess it depends on how strict you want it to be. Do you want an Add method that only takes two parameters of the exact same type (int and int, float and float) ... ? If not, and performance is not super-important, then you can just implement your solution with decimal and it will all work.

If it does have to be strict, and you want specific versions per type, you may want to look into T4 code generation. It's akin to C++'s templates (some people think C++ templates and C# generics are the same, but they're not).

Scott Hanselman wrote an interesting article about it.

like image 111
Roy Dictus Avatar answered Nov 14 '22 20:11

Roy Dictus


Maybe this could be useful: Is there a C# generic constraint for "real number" types?.

It seems that it's not directly possible as you have said. It would be useful to have it.

like image 37
Kioshiki Avatar answered Nov 14 '22 19:11

Kioshiki


The main challenge here is that the jitter has to emit different opcodes depending on whether you're adding floats or ints, so, even though the code looks similar, it's actually quite different behind the scenes. This is doable in C++ (because templates are compiled separately for each type definition), but .NET generics work differently. Take a look at T4 templates as one possible solution (if you really need the ability to compile as float or int separately.)

like image 2
Dan Bryant Avatar answered Nov 14 '22 21:11

Dan Bryant