Partager via


Attributs

Les attributs offrent un moyen puissant d’associer des métadonnées, ou des informations déclaratives, au code (assemblys, types, méthodes, propriétés, etc.). Après avoir associé un attribut à une entité de programme, vous pouvez interroger l’attribut au moment de l’exécution à l’aide d’une technique appelée réflexion.

Les attributs ont les propriétés suivantes :

  • Les attributs ajoutent des métadonnées à votre programme. Les métadonnées sont des informations sur les types définis dans un programme. Tous les assemblys .NET contiennent un ensemble de métadonnées spécifié qui décrit les types et les membres de type définis dans l’assembly. Vous pouvez ajouter des attributs personnalisés pour spécifier les autres informations requises.
  • Les attributs peuvent être appliqués à des assemblys, des modules ou des éléments de programme plus petits, tels que des classes et des propriétés.
  • Les attributs peuvent accepter des arguments de la même façon que les méthodes et les propriétés.
  • Les attributs permettent à un programme d’examiner ses propres métadonnées ou métadonnées dans d’autres programmes à l’aide de la réflexion.

Travailler avec réflexion

Réflexion Les API fournies par Type décrivent les assemblages, les modules et les types. Vous pouvez utiliser la réflexion pour créer dynamiquement une instance d’un type, lier le type à un objet existant ou obtenir le type à partir d’un objet existant et appeler ses méthodes ou accéder à ses champs et propriétés. Lorsque vous utilisez des attributs dans votre code, la réflexion vous permet d’y accéder. Pour plus d’informations, consultez Attributs.

Voici un exemple simple de réflexion avec la GetType() méthode. Tous les types de la Object classe de base héritent de cette méthode, qui est utilisée pour obtenir le type d’une variable :

Remarque

Veillez à ajouter les instructions using System; et using System.Reflection; en haut de votre fichier de code C# (.cs).

// Using GetType to obtain type information:
int i = 42;
Type type = i.GetType();
Console.WriteLine(type);

La sortie affiche le type :

System.Int32

L’exemple suivant utilise la réflexion pour obtenir le nom complet de l’assembly chargé.

// Using Reflection to get information of an Assembly:
Assembly info = typeof(int).Assembly;
Console.WriteLine(info);

Le résultat ressemble à l’exemple suivant :

System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e

Différences de mot clé pour IL

Les mots clés protected C# et internal n’ont aucune signification dans le langage intermédiaire (IL) et ne sont pas utilisés dans les API de réflexion. Les termes correspondants dans IL sont Famille et Assemblage. Voici quelques façons d’utiliser ces termes :

  • Pour identifier une méthode à l’aide de la réflexion internal, utilisez la propriété IsAssembly.
  • Pour identifier une méthode protected internal, utilisez la IsFamilyOrAssembly.

Utiliser des attributs

Les attributs peuvent être placés sur presque n’importe quelle déclaration, bien qu’un attribut spécifique puisse restreindre les types de déclarations sur lesquels il est valide. En C#, vous spécifiez un attribut en plaçant le nom de l’attribut entre crochets ([]) au-dessus de la déclaration de l’entité à laquelle elle s’applique.

Dans cet exemple, vous utilisez l’attribut SerializableAttribute pour appliquer une caractéristique spécifique à une classe :

[Serializable]
public class SampleClass
{
    // Objects of this type can be serialized.
}

Vous pouvez déclarer une méthode avec l’attribut DllImportAttribute :

[System.Runtime.InteropServices.DllImport("user32.dll")]
extern static void SampleMethod();

Vous pouvez placer plusieurs attributs sur une déclaration :

void MethodA([In][Out] ref double x) { }
void MethodB([Out][In] ref double x) { }
void MethodC([In, Out] ref double x) { }

Certains attributs peuvent être spécifiés plusieurs fois pour une entité donnée. L’exemple suivant montre plusieurs utilisations de l’attribut ConditionalAttribute :

[Conditional("DEBUG"), Conditional("TEST1")]
void TraceMethod()
{
    // ...
}

Remarque

Par convention, tous les noms d’attributs se terminent par le suffixe « Attribute » pour les distinguer des autres types dans les bibliothèques .NET. Toutefois, vous n’avez pas besoin de spécifier le suffixe d’attribut lorsque vous utilisez des attributs dans le code. Par exemple, une [DllImport] déclaration équivaut à une [DllImportAttribute] déclaration, mais DllImportAttribute est le nom réel de la classe dans la bibliothèque de classes .NET.

Paramètres d’attribut

De nombreux attributs ont des paramètres, qui peuvent être positionnels, non nommés ou nommés. Le tableau suivant décrit comment utiliser des attributs nommés et positionnels :

Paramètres positionnels

Paramètres du constructeur d’attribut :

Paramètres nommés

Propriétés ou champs de l’attribut :

  • Doit spécifier, ne peut pas omettre
  • Toujours spécifier en premier
  • Spécifier dans un certain ordre
  • Toujours facultatif, omettre quand false
  • Spécifier après les paramètres positionnels
  • Spécifier dans n’importe quel ordre

Par exemple, le code suivant montre trois attributs équivalents DllImport :

[DllImport("user32.dll")]
[DllImport("user32.dll", SetLastError=false, ExactSpelling=false)]
[DllImport("user32.dll", ExactSpelling=false, SetLastError=false)]

Le premier paramètre, le nom de la DLL, est positionnel et vient toujours en premier. Les autres instances sont des paramètres nommés. Dans ce scénario, les deux paramètres nommés ont la valeur false par défaut, afin qu’ils puissent être omis. Reportez-vous à la documentation de l’attribut individuel pour plus d’informations sur les valeurs de paramètre par défaut. Pour plus d’informations sur les types de paramètres autorisés, consultez la section Attributs de la spécification du langage C# .

Cibles d’attribut

La cible d’un attribut est l’entité à laquelle l’attribut s’applique. Par exemple, un attribut peut s’appliquer à une classe, une méthode ou un assembly. Par défaut, un attribut s’applique à l’élément qui le suit. Toutefois, vous pouvez également identifier explicitement l’élément à associer, tel qu’une méthode, un paramètre ou la valeur de retour.

Pour identifier explicitement une cible d’attribut, utilisez la syntaxe suivante :

[target : attribute-list]

Le tableau suivant présente la liste des valeurs possibles target .

Valeur cible S’applique à
assembly Ensemble entier
module Module d’assembly actuel
field Champ dans une classe ou une structure
event Événement
method Méthode ou accesseurs de propriété get et set
param Paramètres de méthode ou paramètres d’accesseur de propriété set
property Propriété
return Valeur de retour d’une méthode, d’un indexeur de propriétés ou d’un accesseur de propriété get
type Struct, classe, interface, énumération ou délégué

Vous pouvez spécifier la field valeur cible pour appliquer un attribut au champ de stockage créé pour une propriété implémentée automatiquement.

L’exemple suivant montre comment appliquer des attributs à des assemblys et des modules. Pour plus d’informations, consultez Attributs communs (C#).

using System;
using System.Reflection;
[assembly: AssemblyTitleAttribute("Production assembly 4")]
[module: CLSCompliant(true)]

L’exemple suivant montre comment appliquer des attributs à des méthodes, des paramètres de méthode et des valeurs de retour de méthode en C#.

// default: applies to method
[ValidatedContract]
int Method1() { return 0; }

// applies to method
[method: ValidatedContract]
int Method2() { return 0; }

// applies to parameter
int Method3([ValidatedContract] string contract) { return 0; }

// applies to return value
[return: ValidatedContract]
int Method4() { return 0; }

Remarque

Quelles que soient les cibles sur lesquelles l’attribut ValidatedContract est défini pour être valide, la return cible doit être spécifiée, même si l’attribut ValidatedContract est défini pour s’appliquer uniquement aux valeurs renvoyées. En d’autres termes, le compilateur n’utilise pas les informations contenues dans le code AttributeUsage pour résoudre les ambiguïtés des cibles d’attribut. Pour plus d’informations, consultez AttributeUsage.

Examiner les façons d’utiliser des attributs

Voici quelques façons courantes d’utiliser des attributs dans le code :

  • Marquez les méthodes de contrôleur qui répondent aux messages POST à l’aide de l’attribut HttpPost . Pour plus d’informations, consultez la HttpPostAttribute classe.
  • Décrivez comment transmettre les paramètres de méthode lors de l’interopérabilité avec du code natif. Pour plus d’informations, consultez la MarshalAsAttribute classe.
  • Décrire les propriétés COM (Component Object Model) pour les classes, méthodes et interfaces.
  • Appelez du code non managé à l’aide de la classe DllImportAttribute.
  • Décrivez votre assemblage en termes de titre, de version, de description ou de marque.
  • Décrire les membres d’une classe à sérialiser pour la persistance.
  • Décrire comment mapper entre les membres de classe et les nœuds XML pour la sérialisation XML.
  • Décrivez les exigences de sécurité pour les méthodes.
  • Spécifiez les caractéristiques utilisées pour appliquer la sécurité.
  • Contrôler les optimisations avec le compilateur just-in-time (JIT) pour que le code reste facile à déboguer.
  • Obtenir des informations sur l'appelant d'une méthode.

Passer en revue les scénarios de réflexion

La réflexion est utile dans les scénarios suivants :