La razón por la que su código no compila se explica por el error del compilador. El tipo contenedor es una definición de tipo genérico, y un tipo genérico construido de dicho tipo no se considera del mismo tipo.
Tengo algunas preguntas:
- Por qué debe ser del tipo
Rational
genérico? Un número racional es definido como un número que se puede expresar como el cociente/fracción de dos enteros (donde el denominador no es 0
). ¿Por qué no hacer que el tipo no sea genérico y simplemente usar int
en todo momento? ¿O piensa que el tipo se use para otros tipos integrales como long
y BigInteger
? En ese caso, considere usar algo como la sugerencia de Aliostad si quiere algún mecanismo de código compartido.
- ¿Por qué quiere que el producto de dos números racionales sea igual a la suma de sus numeradores sobre la suma de sus denominadores? Eso no tiene sentido para mí.
En cualquier caso, parece que quieren ser capaces de 'genéricamente' añadir dos instancias de un tipo 'que se puede añadir'. Desafortunadamente, actualmente no hay forma de expresar una restricción 'tiene un operador de adición adecuado' en C#.
Método n. ° 1: Una solución para esto en C# 4 es utilizar el tipo dynamic
para proporcionarle la semántica deseada de "operador virtual".
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);
}
El operador lanzará si el tipo no tiene un operador de suma adecuado.
Método # 2: Otra forma (más eficiente) es el uso de la expresión de los árboles.
En primer lugar, crear y almacenar en caché un delegado que puede realizar la adición mediante la compilación de la expresión apropiada: (. El constructor estático arrojará si el tipo no tiene un operador de adición adecuada)
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();
}
Entonces emplearla en el operador:
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);
}
cierto es ésta una tarea o que se va a utilizar en el código de producción? Consulte http://msdn.microsoft.com/en-us/library/microsoft.solverfoundation.common.rational%28v=vs.93%29.aspx –
Es posible que desee cambiar el nombre de la clase a Rational ... –
¿Por qué estás creando una clase que maneja el framework de forma inmediata? Si esto es tarea, esta es una manera horrible de hacer esto. –