web-dev-qa-db-fra.com

Comment créer des attributs autorisés en double

J'utilise un attribut personnalisé hérité d'une classe d'attributs. Je l'utilise comme ceci:

    [MyCustomAttribute("CONTROL")]
    [MyCustomAttribute("ALT")]
    [MyCustomAttribute("SHIFT")]
    [MyCustomAttribute("D")]
    public void setColor()
{

}

Mais l'erreur "attribut" MyCustomAttribute "en double" est affichée.
Comment puis-je créer un attribut autorisé en double?

87
ebattulga

Collez un attribut AttributeUsage sur votre classe d'attribut (yep, c'est une bouchée) et définissez AllowMultiple sur true:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public sealed class MyCustomAttribute: Attribute
168
Anton Gogolev

AttributeUsageAttribute ;-p

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class MyAttribute : Attribute
{}

Notez cependant que si vous utilisez ComponentModel (TypeDescriptor), il ne prend en charge qu'une seule instance d'attribut (par type d'attribut) par membre; la réflexion brute prend en charge n'importe quel nombre ...

19
Marc Gravell

la solution d'Anton est correcte, mais il y a n autre gotcha .

En bref, à moins que votre attrbiute personnalisé ne remplace TypeId, y accéder via PropertyDescriptor.GetCustomAttributes () ne renverra qu'une seule instance de votre attribut.

12
mcdrewski

Par défaut, Attributes est limité à une seule application à un seul champ/propriété/etc. Vous pouvez le voir dans la définition de la classe Attribute sur MSDN :

[AttributeUsageAttribute(..., AllowMultiple = false)]
public abstract class Attribute : _Attribute

Par conséquent, comme d'autres l'ont noté, toutes les sous-classes sont limitées de la même manière, et si vous avez besoin de plusieurs instances du même attribut, vous devez définir explicitement AllowMultiple sur true:

[AttributeUsage(..., AllowMultiple = true)]
public class MyCustomAttribute : Attribute

Sur les attributs qui autorisent plusieurs utilisations, vous devez également remplacer la propriété TypeId pour vous assurer que des propriétés telles que PropertyDescriptor.Attributes fonctionne comme prévu. La façon la plus simple de procéder consiste à implémenter cette propriété pour renvoyer l'instance d'attribut elle-même:

[AttributeUsage(..., AllowMultiple = true)]
public class MyCustomAttribute : Attribute
{
    public override object TypeId
    {
        get
        {
            return this;
        }
    }
}

(Publier cette réponse non pas parce que les autres ont tort, mais parce que c'est une réponse plus complète/canonique.)

6
Ian Kemp

Comme alternative, pensez à repenser votre attribut pour permettre une séquence.

[MyCustomAttribute(Sequence="CONTROL,ALT,SHIFT,D")]

ou

[MyCustomAttribute("CONTROL-ALT-SHIFT-D")]

puis analysez les valeurs pour configurer votre attribut.

Pour un exemple de cela, consultez le AuthorizeAttribute dans le code source ASP.NET MVC à www.codeplex.com/aspnet .

3
tvanfosson

Après avoir ajouté AttributeUsage, assurez-vous d'ajouter cette propriété à votre classe Attribute

public override object TypeId
{
  get
  {
    return this;
  }
}
2
Axle