En ajoutant une classe intermédiaire et un dictionnaire, la spécialisation est possible .
Pour spécialiser sur T, nous créons une interface générique, ayant une méthode appelée (par exemple) Apply. Pour les classes spécifiques, cette interface est implémentée, définissant la méthode Apply spécifique à cette classe. Cette classe intermédiaire est appelée la classe de traits.
Cette classe de traits peut être spécifiée comme paramètre dans l'appel de la méthode générique, qui prend alors (bien sûr) toujours la bonne implémentation.
Au lieu de la spécifier manuellement, la classe de traits peut également être stockée dans un fichier global de type IDictionary<System.Type, object>
. Il peut ensuite être recherché et voilà, vous avez une véritable spécialisation.
Si cela vous convient, vous pouvez l'exposer dans une méthode d'extension.
class MyClass<T>
{
public string Foo() { return "MyClass"; }
}
interface BaseTraits<T>
{
string Apply(T cls);
}
class IntTraits : BaseTraits<MyClass<int>>
{
public string Apply(MyClass<int> cls)
{
return cls.Foo() + " i";
}
}
class DoubleTraits : BaseTraits<MyClass<double>>
{
public string Apply(MyClass<double> cls)
{
return cls.Foo() + " d";
}
}
// Somewhere in a (static) class:
public static IDictionary<Type, object> register;
register = new Dictionary<Type, object>();
register[typeof(MyClass<int>)] = new IntTraits();
register[typeof(MyClass<double>)] = new DoubleTraits();
public static string Bar<T>(this T obj)
{
BaseTraits<T> traits = register[typeof(T)] as BaseTraits<T>;
return traits.Apply(obj);
}
var cls1 = new MyClass<int>();
var cls2 = new MyClass<double>();
string id = cls1.Bar();
string dd = cls2.Bar();
Voir ceci lien Pour une description détaillée et des exemples, consultez mon récent blog et les articles qui suivent.