The reason your code does not compile is due to a compiler error. A containing type is a definition of a generic type, and a generic type built from that type is not considered the same type.
I have a few questions:
- Why should the
Rational type be generic? A rational number is defined as a number that can be expressed as the quotient / fractional number of two integers (where the denominator is not 0 ). Why not make the type non-generic and just use int all along? Or do you assume that this type is used for other integral types such as long and BigInteger ? In this case, consider using something like Aliostad's suggestion if you want to use a code-sharing mechanism. - Why do you want the product of two rational numbers equal the sum of their numerators over the sum of their denominators? It makes no sense to me.
In any case, it seems to you that you want to be able to "generally" add two instances of the "addable" type. Unfortunately, there is currently no way to express a C expression with a suitable addition operator in C #.
Method # 1:. One way around this in C # 4 is to use the dynamic type to give you the desired semantics of the virtual operator.
public static Racional<T> operator *(Racional<T> a, Racional<T> b) { var nominatorSum = (dynamic)a.Nominator + b.Nominator; var denominatorSum = (dynamic)a.Denominator + b.Denominator; return new Racional<T>(nominatorSum, denominatorSum); }
The operator will throw if the type does not have a suitable addition operator.
Method # 2: Another (more efficient) way is to use expression trees.
First create and close a delegate that can perform the addition by compiling the corresponding expression:
private readonly static Func<T, T, T> Adder; static Racional() { var firstOperand = Expression.Parameter(typeof(T), "x"); var secondOperand = Expression.Parameter(typeof(T), "y"); var body = Expression.Add(firstOperand, secondOperand); Adder = Expression.Lambda<Func<T, T, T>> (body, firstOperand, secondOperand).Compile(); }
(The static constructor will throw if the type does not have a suitable addition operator.)
Then use it in the statement:
public static Racional<T> operator *(Racional<T> a, Racional<T> b) { var nominatorSum = Adder(a.Nominator, b.Nominator); var denominatorSum = Adder(a.Denominator, b.Denominator); return new Racional<T>(nominatorSum, denominatorSum); }