Y at-il une approche raisonnable des paramètres de type « par défaut » en C # Generics?
-
22-08-2019 - |
Question
Dans les modèles de C, on peut spécifier qu'un certain type de paramètre est une valeur par défaut. C'est à dire. sauf indication explicite, il utilisera le type T.
Cela peut être fait ou approximée en C #?
Je cherche quelque chose comme:
public class MyTemplate<T1, T2=string> {}
Pour qu'une instance du type qui ne spécifie pas explicitement T2
:
MyTemplate<int> t = new MyTemplate<int>();
Ce serait essentiellement:
MyTemplate<int, string> t = new MyTemplate<int, string>();
En fin de compte, je suis à la recherche d'un cas où il y a un modèle qui est assez largement utilisé, mais je suis envisage d'étendre avec un paramètre de type supplémentaire. Je pourrais sous-classe, je suppose, mais j'étais curieux de savoir s'il y avait d'autres options dans cette veine.
La solution
Subclassing est la meilleure option.
Je sous-classe principale de votre classe générique:
class BaseGeneric<T,U>
avec une classe spécifique
class MyGeneric<T> : BaseGeneric<T, string>
Il est donc facile de garder votre logique en un seul endroit (la classe de base), mais aussi facile à fournir à la fois les options d'utilisation. En fonction de la classe, il y a probablement très peu de travail supplémentaire nécessaire pour y arriver.
Autres conseils
Une solution est subclassing. Un autre j'utiliser à la place, est des méthodes d'usine (combinée avec mot-clé var).
public class MyTemplate<T1,T2>
{
public MyTemplate(..args..) { ... } // constructor
}
public static class MyTemplate{
public static MyTemplate<T1,T2> Create<T1,T2>(..args..)
{
return new MyTemplate<T1, T2>(... params ...);
}
public static MyTemplate<T1, string> Create<T1>(...args...)
{
return new MyTemplate<T1, string>(... params ...);
}
}
var val1 = MyTemplate.Create<int,decimal>();
var val2 = MyTemplate.Create<int>();
Dans l'exemple ci-dessus val2
est de type MyTemplate<int,string>
et non un type dérivé de celui-ci.
Un type class MyStringTemplate<T>:MyTemplate<T,string>
n'est pas le même type que MyTemplate<T,string>
.
Cela pourrait poser des problèmes dans certains scénarios.
Par exemple, vous ne pouvez pas lancer une instance de MyTemplate<T,string>
à MyStringTemplate<T>
.
vous pouvez également créer une surcharge de classe comme si
public class MyTemplate<T1, T2> {
public T1 Prop1 { get; set; }
public T2 Prop2 { get; set; }
}
public class MyTemplate<T1> : MyTemplate<T1, string>{}
C # ne supporte pas une telle fonctionnalité.
Comme vous l'avez dit, vous pouvez sous-classe (si ce n'est pas scellé et dupliquer toutes les déclarations du constructeur), mais il est une chose complètement différente.
Malheureusement C # ne supporte pas ce que vous essayez de faire. Ce serait une caractéristique difficile à appliquer, étant donné que le type par défaut pour un paramètre devrait respecter les contraintes génériques et créerait probablement des maux de tête lorsque le CLR a essayé d'assurer la sécurité-type.