2011-02-02 7 views
77

J'ai essayé plusieurs fois mais je n'arrive toujours pas à comprendre l'utilisation des attributs personnalisés (j'ai déjà passé beaucoup de liens).Comment créer un attribut personnalisé en C#

Quelqu'un peut-il m'expliquer s'il vous plaît un exemple très basique d'un attribut personnalisé avec du code?

Répondre

69

Alors que le code pour créer une coutume Attribute est assez simple, il est beaucoup plus important que vous compreniez quels sont les attributs:

Les attributs sont des métadonnées compilées dans votre programme. Les attributs eux-mêmes n'ajoutent aucune fonctionnalité à une classe, une propriété ou un module, seulement des données. Cependant, en utilisant la réflexion, on peut tirer parti de ces attributs afin de créer des fonctionnalités. Ainsi, par exemple, regardons Validation Application Block, de Enterprise Library. Si vous regardez un exemple de code, vous verrez:

/// <summary> 
    /// blah blah code. 
    /// </summary> 
    [DataMember] 
    [StringLengthValidator(8, RangeBoundaryType.Inclusive, 8, RangeBoundaryType.Inclusive, MessageTemplate = "\"{1}\" must always have \"{4}\" characters.")] 
    public string Code { get; set; } 

De l'extrait ci-dessus, on peut deviner que le code sera toujours validé, chaque fois changé, en conséquence les règles du validateur (dans l'exemple, avoir au moins 8 caractères et au plus 8 caractères). Mais la vérité est que l'attribut ne fait rien, ajoute seulement des métadonnées à la propriété.

Toutefois, la bibliothèque d'entreprise a une méthode Validation.Validate qui examinera votre objet, et pour chaque propriété, elle vérifiera si le contenu enfreint la règle informée par l'attribut. Donc, voilà comment vous devriez penser aux attributs - un moyen d'ajouter des données à votre code qui pourraient être utilisées plus tard par d'autres méthodes/classes/etc.

+0

vais vraiment aimer la réponse et spécialement ", une autre question que je peux mettre même condition dans l'ensemble de déclaration du code ci-dessus, donc comment différent des attributs, –

+1

@slash: Pouvez-vous reformuler cela? Je n'ai pas bien compris la question –

+1

Je pense que la barre oblique voulait dire la différence entre utiliser des attributs et mettre le vrai code de validation dans le setter de la propriété Réponse: Alors que l'écriture du code peut être faite pour valider la valeur, Les attributs ne sont que des "méta-données" Un autre code devrait être intéressé par les attributs que vous utilisez, les lire et effectuer des actions basées sur ces attributs, comme par exemple @BrunoBrant – romar

190

Vous commencez par écrire une classe qui dérive de Attribute:

public class MyCustomAttribute: Attribute 
{ 
    public string SomeProperty { get; set; } 
} 

Ensuite, vous pouvez décorer quoi que ce soit (classe, méthode, propriété, ...) avec cet attribut:

[MyCustomAttribute(SomeProperty = "foo bar")] 
public class Foo 
{ 

} 

et enfin, vous utiliseriez la réflexion pour l'extraire:

var customAttributes = (MyCustomAttribute[])typeof(Foo).GetCustomAttributes(typeof(MyCustomAttribute), true); 
if (customAttributes.Length > 0) 
{ 
    var myAttribute = customAttributes[0]; 
    string value = myAttribute.SomeProperty; 
    // TODO: Do something with the value 
} 

Vous pourriez limiter les types de cible auquel cet attribut personnalisé peut être appliqué en utilisant l'attribut AttributeUsage:

/// <summary> 
/// This attribute can only be applied to classes 
/// </summary> 
[AttributeUsage(AttributeTargets.Class)] 
public class MyCustomAttribute : Attribute 

choses importantes à savoir sur les attributs:

  • Les attributs sont des métadonnées.
  • Ils sont cuits dans l'ensemble à lors de la compilation, ce qui a de très graves implications sur la façon dont vous pourriez définir leurs propriétés. Seules les valeurs constantes (connues au moment de la compilation) sont acceptées
  • La seule façon de donner un sens et d'utiliser les attributs personnalisés est d'utiliser Reflection. Donc, si vous n'utilisez pas la réflexion à l'exécution pour les récupérer et pour décorer quelque chose avec un attribut personnalisé, n'attendez pas beaucoup de choses.
  • L'heure de création des attributs est non déterministe. Ils sont instanciés par le CLR et vous n'avez absolument aucun contrôle dessus.
+1

Où, dans quelle fonction/classe, dois-je utiliser la réflexion pour l'extraire? –

+0

@Hasan A Yousef, par exemple dans Entity Framework il y a un attribut "clé" qui dit à framework: Cette propriété doit être considérée comme clé primaire . Lors de la création d'ORM, les attributs sont très utiles – Parsa

+0

Comment accéder à un attribut personnalisé sur une propriété et non sur une classe? – Canvas

6

utilisant/copie Darin Dimitrov's great response, voici comment accéder à un attribut personnalisé sur une propriété et non une classe:

La propriété décorée [de classe Foo]:

[MyCustomAttribute(SomeProperty = "This is a custom property")] 
public string MyProperty { get; set; } 

Récupérer le:

PropertyInfo propertyInfo = typeof(Foo).GetProperty(propertyToCheck); 
object[] attribute = propertyInfo.GetCustomAttributes(typeof(MyCustomAttribute), true); 
if (attribute.Length > 0) 
{ 
    MyCustomAttribute myAttribute = (MyCustomAttribute)attribute[0]; 
    string propertyValue = myAttribute.SomeProperty; 
} 

Vous pouvez lancer ceci dans une boucle et utiliser la réflexion pour accéder à cet attribut personnalisé sur chaque propriété de classe Foo, ainsi:

foreach (PropertyInfo propertyInfo in Foo.GetType().GetProperties()) 
{ 
    string propertyName = propertyInfo.Name; 

    object[] attribute = propertyInfo.GetCustomAttributes(typeof(MyCustomAttribute), true); 
    // Just in case you have a property without this annotation 
    if (attribute.Length > 0) 
    { 
     MyCustomAttribute myAttribute = (MyCustomAttribute)attribute[0]; 
     string propertyValue = myAttribute.SomeProperty; 
     // TODO: whatever you need with this propertyValue 
    } 
} 

majeur grâce à vous, Darin !!

Questions connexes