C#: types Génériques qui ont un constructeur?
J'ai le C# suivants du code de test:
class MyItem
{
MyItem( int a ) {}
}
class MyContainer< T >
where T : MyItem, new()
{
public void CreateItem()
{
T oItem = new T( 10 );
}
}
Visual Studio ne peut pas compiler, l'erreur est à la ligne où la "nouvelle" est utilisé:
'T': cannot provide arguments when creating an instance of a variable type
Est-il possible en C# pour créer un objet de type générique avec des non-constructeur sans paramètre? Pas de problème pour faire ce genre de chose dans les modèles C++, donc je suis très curieux de savoir pourquoi je ne peux pas faire la même chose en C#. Peut-être quelques autres " où " est nécessaire, ou la syntaxe est différente?
Vous devez vous connecter pour publier un commentaire.
Il peut être fait avec réflexion:
Mais il n'y a pas de contrainte générique pour s'assurer que
T
implémente l'souhaité constructeur, donc je ne le conseille pas de faire cela, sauf si vous êtes prudent de déclarer que constructeur dans chaque type qui implémente l'interface.new()
contrainte se traduit par uneActivator.CreateInstance()
appel.C#, et VB.Net pour cette question, ne prennent pas en charge la notion de contraindre un générique pour avoir un constructeur avec paramètres spécifiques. Il ne supporte que les contraignant d'avoir un constructeur vide.
Un travail autour de est de demander à l'appelant de passer dans une usine lambda de créer de la valeur. Par exemple
Site d'appel
Il n'y a pas une telle contrainte générique, de sorte qu'il n'est pas possible directement (ce qui est un CLR limitation). Si vous voulez cela, vous devez fournir une usine de classe (qui a un constructeur sans paramètre), et de le passer comme deuxième paramètre de type générique.
De l'OMI, la meilleure approche ici est une méthode initialize, c'est à dire
Cependant, vous pouvez faire ce que vous voulez avec
Expression
(mais sans compilation de soutien):Noter que cette caches et réutilise le délégué pour la performance.
Activator.CreateInstance()
? Si je comprends bien, qu'il n'ait le temps de compilation de soutien, et les deux lancent une erreur d'exécution si la durée de constructeur n'existe pas.Un modèle que j'utilise est d'avoir la contrainte de la classe implémente une interface qui définit une méthode Init avec la signature appropriée: