Cela provoque une exception au moment de la compilation:
public sealed class ValidatesAttribute<T> : Attribute
{
}
[Validates<string>]
public static class StringValidation
{
}
Je me rends compte que C # ne prend pas en charge les attributs génériques. Cependant, après beaucoup de recherches sur Google, je n'arrive pas à trouver la raison.
Est-ce que quelqu'un sait pourquoi les types génériques ne peuvent pas dériver Attribute
? Des théories?
c#
generics
.net-attributes
Bryan Watts
la source
la source
abstract class Base<T>: Attribute {}
qui pourraient être utilisés pour créer des non classes dérivées génériques comme ceci:class Concrete: Base<MyType> {}
[DependsOnProperty<Foo>(f => f.Bar)]
ou[ForeignKey<Foo>(f => f.IdBar)]
...Réponses:
Eh bien, je ne peux pas dire pourquoi il n'est pas disponible, mais je peux confirmer que ce n'est pas un problème CLI. La spécification CLI ne le mentionne pas (pour autant que je puisse voir) et si vous utilisez directement IL, vous pouvez créer un attribut générique. La partie de la spécification C # 3 qui l'interdit - la section 10.1.4 «Spécification de base de classe» ne donne aucune justification.
La spécification ECMA C # 2 annotée ne donne pas non plus d'informations utiles, bien qu'elle fournisse un exemple de ce qui n'est pas autorisé.
Ma copie de la spécification annotée C # 3 devrait arriver demain ... Je vais voir si cela donne plus d'informations. Quoi qu'il en soit, c'est définitivement une décision de langue plutôt qu'une décision d'exécution.
EDIT: Réponse d'Eric Lippert (paraphrasé): pas de raison particulière, sauf pour éviter la complexité du langage et du compilateur pour un cas d'utilisation qui n'ajoute pas beaucoup de valeur.
la source
Un attribut décore une classe au moment de la compilation, mais une classe générique ne reçoit ses informations de type final qu'au moment de l'exécution. Étant donné que l'attribut peut affecter la compilation, il doit être "complet" au moment de la compilation.
Consultez cet article MSDN pour plus d'informations.
la source
Je ne sais pas pourquoi ce n'est pas autorisé, mais c'est une solution de contournement possible
la source
Ce n'est pas vraiment générique et vous devez toujours écrire une classe d'attribut spécifique par type, mais vous pouvez peut-être utiliser une interface de base générique pour coder un peu de manière défensive, écrire moins de code que nécessaire, tirer parti du polymorphisme, etc.
la source
C'est une très bonne question. Dans mon expérience avec des attributs, je pense que la contrainte est en place parce que lorsque l'on réfléchit sur un attribut créerait une condition dans laquelle vous devez vérifier toutes les permutations possibles de type:
typeof(Validates<string>)
,typeof(Validates<SomeCustomType>)
, etc ...À mon avis, si une validation personnalisée est requise selon le type, un attribut peut ne pas être la meilleure approche.
Peut-être qu'une classe de validation qui prend un
SomeCustomValidationDelegate
ou unISomeCustomValidator
comme paramètre serait une meilleure approche.la source
Ce n'est pas actuellement une fonctionnalité en langage C #, mais il y a beaucoup de discussions sur le dépôt officiel en langage C # .
De quelques notes de réunion :
la source
Ma solution de contournement est quelque chose comme ceci:
la source