9
votes

Puis-je dicter qu'un paramètre de type C # ne doit être qu'un type d'interface?

Je voudrais mettre en œuvre une classe C # générique qui ressemble à ce qui suit: xxx

ceci échoue car c # autorisera uniquement des types après l'interface de la classe de base, alors j'essaye donc : xxx

mais je trouve que c # ne permet pas cette forme de contrainte de type. Seul où T: struct et où T: Classe sont autorisés.

Comment puis-je dicter qu'un paramètre de type ne doit être qu'un type d'interface? < / p>


1 commentaires

qu'essayez-vous d'atteindre? Je ne peux pas vraiment penser à une situation où une telle contrainte serait nécessaire.


5 Réponses :


6
votes

Fondamentalement, vous ne pouvez pas.

Vous pouvez faire une continuité d'une interface spécifique, mais pas un général pour toutes les interfaces. Vous pouvez donc contraindre à iEnumérable par exemple, mais pas aucune interface .

De quoi avez-vous besoin de cela pour de toute façon?


1 commentaires

J'ai remarqué que toutes les classes découlant de Foobar finissent également par la mise en œuvre de T. Je pensais que je pouvais peut-être appliquer ce cas en déplaçant le implémente bla de mes classes dérivées sur la classe de base Foobar.



1
votes

Vous ne pouvez pas en mots simples.


0 commentaires

0
votes

Ceci échoue car c # autorisera uniquement des types après l'interface de la classe de base

Cette contrainte est due à l'absence de multiples héritage dans C #. Le héritage multiple peut être approché par l'utilisation d'interfaces car les méthodes de remplacement sont explicites. De la même manière qu'une classe ne peut que prolonger une autre classe, mais peut implémenter plusieurs interfaces. L'astuce ici est que la classe d'implémentation doit définir le corps d'une méthode, de sorte que la mise en œuvre soit spécifique sur laquelle la méthode est appelée.

Utilisation d'un endroit où Limit T peut être appliqué à une classe ou plusieurs interfaces. Vous ne pouvez pas limiter la plage à plusieurs classes.


0 commentaires

1
votes

Je crois que vous avez mal compris la signification de où T: struct et où T: classe .

Un générique type contrainte comme si cela signifie que t doit être un type type de valeur ou un type de référence respectivement.

Toutefois, le but d'une interface est de définir un contrat , qui est un concept totalement différent, par rapport à la Semantitique de type de référence par rapport à la sémantique de référence de référence.

Par conséquent, une restriction comme où T: interface n'a aucun sens.

Si vous voulez en savoir plus, je vous suggère de lire le Guide de programmation C # sur les contraintes de type:


1 commentaires

Une contrainte de type d'interface aurait un sens s'il existait des caractéristiques linguistiques qui seraient utilisables sur ces types et seuls de tels types. Par exemple, il serait très utile que l'on puisse définir un wrapper : t où T: interface (foo) , avec la sémantique que la classe définirait un champ foo de type t et implémente explicitement chaque membre m de l'interface t en l'intervenant foo.m . Une telle installation générale ne serait pas conquérienne avec des classes, même avec le support CLR, mais pourrait être très utile avec des interfaces si le CLR a fourni les caractéristiques nécessaires.



5
votes

Le problème réel avec ce code est que vous héritez d'un paramètre de type.

essayer de compiler xxx

échouera toujours avec: Erreur CS0689: impossible de dériver de 'T' parce qu'il s'agit d'un paramètre de type.

Je pense que cela serait parfaitement raisonnable au moins dans le cas des classes abstraites, et je voulais aussi cette fonctionnalité, mais le compilateur C # ne vous laissera pas fais ça.


1 commentaires

+1 Pour mentionner le noyau du problème (dériver des paramètres de type).