La raison pour laquelle votre code ne compile pas est expliquée par l'erreur du compilateur. Le type conteneur est une définition de type générique, et un type générique construit à partir de ce type n'est pas considéré comme étant le même type.
J'ai quelques questions :
- Pourquoi le type
Rational
doit-il être générique ? Un nombre rationnel est défini comme un nombre qui peut être exprimé comme le quotient / la fraction de deux entiers (où le dénominateur n'est pas 0
). Pourquoi ne pas rendre le type non-générique et simplement utiliser int
partout ? Ou avez-vous l'intention que le type soit utilisé pour d'autres types intégraux tels que long
et BigInteger
? Dans ce cas, envisagez d'utiliser quelque chose comme la suggestion d'Aliostad si vous voulez un mécanisme de partage de code.
- Pourquoi voulez-vous que le produit de deux nombres rationnels soit égal à la somme de leurs numérateurs sur la somme de leurs dénominateurs ? Cela n'a pas de sens pour moi.
En tout cas, il semble que vous vouliez être capable d'ajouter de manière 'générique' deux instances d'un type 'addable'. Malheureusement, il n'y a actuellement aucun moyen d'exprimer une contrainte de type 'possède un opérateur d'addition approprié' en C#.
Méthode n°1 : Une solution de contournement pour cela en C# 4 est d'utiliser le type dynamic
pour vous donner les sémantiques d'"opérateur virtuel" désirées.
public static Racional operator *(Racional a, Racional b)
{
var sommeNumérateur = (dynamic)a.Numérateur + b.Numérateur;
var sommeDénominateur = (dynamic)a.Dénominateur + b.Dénominateur;
return new Racional(sommeNumérateur, sommeDénominateur);
}
L'opérateur va générer une erreur si le type n'a pas d'opérateur d'addition approprié.
Méthode n°2 : Une autre (plus efficace) méthode est d'utiliser des expressions d'arbre.
Tout d'abord, créez et mettez en cache un délégué qui peut effectuer l'addition en compilant l'expression appropriée :
private readonly static Func Adder;
static Racional()
{
var premierOpérande = Expression.Parameter(typeof(T), "x");
var deuxièmeOpérande = Expression.Parameter(typeof(T), "y");
var corps = Expression.Add(premierOpérande, deuxièmeOpérande);
Adder = Expression.Lambda>
(corps, premierOpérande, deuxièmeOpérande).Compile();
}
(Le constructeur statique va générer une erreur si le type n'a pas d'opérateur d'addition approprié.)
Ensuite, utilisez-le dans l'opérateur :
public static Racional operator *(Racional a, Racional b)
{
var sommeNumérateur = Adder(a.Numérateur, b.Numérateur);
var sommeDénominateur = Adder(a.Dénominateur, b.Dénominateur);
return new Racional(sommeNumérateur, sommeDénominateur);
}