L'un des avantages avec des modèles C ++ est que vous (implicitement) peut nécessiter une certaine signature de type (E.G. Type T doit avoir une fonction X qui ne prend aucun paramètre et retourne un int). C # Generics supporte-t-il quelque chose de similaire? p>
Je suis au courant des contraintes basées sur la classe de base ou l'interface, mais ce n'est pas ce que je cherche. P>
(en tant que programmeur C ++ l'apprentissage C #, je me tromperais peut-être que ceci est une fonctionnalité que vous voudriez en C #. Toute commentaires sur cela serait également apprécié ...) P>
7 Réponses :
Il existe 5 types de contraintes que vous pouvez mettre sur des génériques dans .NET: p>
Cette page affiche plus d'informations. P>
"Je suis au courant des contraintes basées sur la classe de base ou l'interface, mais ce n'est pas ce que je cherche."
Rien sauf pour les contraintes que vous avez déjà vues (qui font, pour être juste, couvrir de nombreux scénarios communs). Il y a quelques solutions de contournement communes: p>
dynamique code>, dans 4.0 li>
- Tapis de canard manuel à l'aide de la réflexion ou de la génération IL, etc. LI>
ul>
Aucun de ceux-ci n'a de vérification de type statique, etc., cependant. P>
Dynamique est probablement le plus proche que je puisse obtenir. En fait, je pense souvent à des modèles C ++ comme une "langue dynamique de l'heure de la compilation" (ce qui est probablement une phrase qui n'a aucun sens pour personne, mais moi :)
@TOBIAS J'aurais allé avec "Début vérifié statique-Tapé"; p ( dynamique code> a des implications de l'exécution, mais je sais ce que vous voulez dire)
et tout à coup, ça a du sens pour tout le monde :)
Oui, à travers une interface. Vous pouvez définir un objet générique qui a un type qui doit avoir une interface spécifique mise en œuvre. Dans cette interface, vous feriez essentiellement un objet ajouté à ce générique, la liste, par exemple, d'avoir une signature spécifique. P>
Que ce soit ou non ce que vous êtes pas em> à la recherche, c'est comme ça que vous l'accomplissez. :) p>
Cela ne couvre toujours pas toutes les options, bien que - constructeurs avec des paramètres, des opérateurs, des méthodes statiques, etc.
@Marc Eh bien il n'y a pas une solution parfaite dans cette situation - comme vous l'avez noté dans votre réponse. L'OP va devoir faire plier un peu pour accomplir sa tâche. Et il n'a peut-être pas besoin d'aucune des choses que vous avez mentionnées. Il veut que sa classe générique soit conforme à "la fonction x qui ne prend aucun paramètre et retourne un int"
@MARC, je suis d'accord et soutenir les contraintes sur les constructeurs non par défaut serait bien IMHO. Les autres, pas tellement, surtout i> opérateurs :)
@Marc mais par tous les moyens, il s'agit simplement d'une solution en conserve. Il est plus que bienvenu pour attaquer cela de n'importe quel angle qui correspond à ses besoins :)
Cela nécessite le type de paramètre de type pour répondre aux besoins de la classe générique qui n'est parfois pas ce que vous voulez. (Je n'essaie pas de résoudre un problème particulier, mais essayant de comprendre quelles possibilités C # Generics fournit).
non. C'est ce que interface code> s est pour. Créez une interface code> code> qui définit le contrat que vous souhaitez appliquer dans les contraintes de type. Puis spécifie que dans les contraintes. P>
Nope, non supporté en C #. Comme vous l'avez dit, la chose la plus proche nécessite que les classes impliquent une interface commune. P>
vous pourrait em> essayer d'imiter le comportement avec la réflexion, en recherchant la méthode par la signature, mais c'est une contrainte d'exécution et non une contrainte de compilation. P>
Non, c # n'a pas de contraintes comme ça. p>
Comme vous le savez, les contraintes génériques ne peuvent appliquer que l'héritage d'une classe de base ou d'une interface, ou quelques autres contraintes (contrainte de constructeur Vous pourriez être capable d'atteindre votre comportement souhaité en utilisant nouveau () code>, contrainte de type de référence classe code >, contrainte de type de valeur struct code>). p>
Par exemple, func int code>. Func DateTime code> et renvoie un int code>, etc ... p>
Non, ce n'est pas possible. Il est principalement causé par les différences entre les modèles C ++ et les génériques C #: p>
Lorsque vous compilez un modèle C ++, le code résultant a des types tels que Lorsque vous compilez un type générique C #, vous créez un seul type générique: en C # 4, vous pouvez obtenir un effet quelque peu similaire à ce type de modèles utilisant vecteur vecteur Liste dynamique code>, mais cela ne pas em> vérification du temps de compilation, ce qui signifie que vous perdez la sécurité - Vous pouvez mettre un type qui n'a pas les membres appropriés et vous ne le découvrirez pas avant d'atteindre cette ligne de code au moment de l'exécution. P>
Mais les contraintes d'interface sont déjà un moyen assez difficile d'exprimer quelque chose comme
t implémente une méthode x () correspondant à une signature code>, ne pensez-vous pas?