I'm currently implementing a simple version of algorithmic differentiation with operator overloading in C#. I'm trying to figure out how to design generic math functions that works for with ordinary doubles and my own class "ADouble" that works like a double, but overloads arithmetic operators like +,*,- and so forth.
For instance, i would like to create a function like
Public T MathFunction<T>(T x) where T : "is either double or Adouble"
{
if (x > 0)
return new T(1.0)
else
// something
}
that works for both doubles and ADoubles. In this case it's necessary for me to "new up" a specific value (here 1.0). In other cases i might have to do something like
Public T MathFunction<T>(T x) where T : "is either double or Adouble"
{
T temporaryVar = 2*x;
// .. More calculations
return "some T";
}
I have implemented the necessary interfaces to do a comparison like the above, but i cannot get the rest to work.
I can instantiate my ADouble class with a double by, say
Adouble myADouble = new ADouble(12.3);
but doubles does not have a constructor that works that way, obviously. I've tried different things. First of all i thought of something like
if (typeof(T) == typeof(ADouble)
return new ADouble(1.0)
but this does not work, since the function cannot cast ADouble to a T explicitly (which i understand).
Does anyone have a suggestion on how i could go about implementing generic calculation functions that works with my ADouble class and doubles? Or is the only option to make multiple methods with different signatures? Different suggestions for designs is also greatly appreciated.
Or is the only option to make multiple methods with different signatures?
Called "method overloading".
Yes. This is the correct way to express your "type A or type B" constraint, especially since even if you could successfully express that as a generic constraint, you are still left with the challenge of calling the appropriate constructor.
There is no mechanism in C# generics by which the statement return new T(1.0);
could be made to compile successfully. Doing so would require some syntax that additionally constrains the types to those with a constructor that has a single parameter of type double
, and there is no such feature in C#.
this does not work, since the function cannot cast ADouble to a T explicitly
Actually, it's that it can't cast implicitly. But, close enough. :)
That would be the next hurdle you'd have to clear. Ironically, this is the simplest. The issue there is that, as you wrote the expression, the compiler knows enough about what's going on to know it can't guarantee the cast will succeed. But if you cast the value to object
first, you can then cast it to T
without the compiler complaining.
Not that I'm suggesting doing that, mind you. The real issue here is that you are trying to use generic syntax for something that really isn't generic. Generic code is for where you can use any type, or at least a broadly constrained type. If you have specific types in mind, and especially if the implementation is different for each specific type, then you should not be using generics.
In that situation, method overloading is much more appropriate.
Aside: assuming your ADouble
type is literally equivalent to double
, and you can implement a conversion without any loss of data, you should consider writing an implicit conversion, to help make the types interchangeable. That would look something like this:
public static implicit operator ADouble(double value)
{
return new ADouble(value);
}
Then you can initialize ADouble
values with simple assignments, like:
ADouble adouble = 1.0;