Contexte général
Dans le développement avec C#, les attributs constituent un mécanisme puissant permettant d'ajouter des informations déclaratives au code source. Ces éléments fournissent de manière déclarative des métadonnées concernant le code, influençant ainsi le comportement de l'application. Cette analyse examine en détail la définition, la catégorisation et les scénarios d'utilisation des attributs selon les spécifications du langage.
Spécifications des attributs
Les spécifications d'attributs consistent à appliquer des attributs prédéfinis aux déclarations. Ils peuvent être positionnés dans le scope global ainsi que sur divers niveaux de déclaration tels que les types, membres de classes, membres d'interfaces, membres de structures, membres d'énumérations, déclarations d'accesseurs et listes de paramètres formels. Les attributs sont indiqués entre crochets et peuvent incorporer des arguments positionnels et nommés, dont l'ordre n'affecte pas leur traitement. Le nom de l'attribut identifie une classe d'attribut existante, faute de quoi une erreur de compilation survient.
Classes d'attributs
Les classes d'attributs adoptent généralement le suffixe Attribute, comme illustré par [Creator("Anders Hejlsberg")]. Lorsqu'une classe d'attribut existe avec ou sans le suffixe Attribute, cela crée une ambiguïté entraînant une erreur de compilation. Les instances de classes d'attributs sont initialisées via des arguments positionnels et nommés.
Instances d'attributs
Les instances d'attributs représentent les objets qui incarnent les attributs pendant l'exécution. Le processus de compilation détermine un constructeur d'instance de classe d'attribut pouvant être invoqué à l'exécution, tout en conservant les listes d'arguments positionnels et nommés. La récupération des instances d'attributs à l'exécution utilise ces données pour initialiser les instances de classe d'attribut.
Attributs prédéfinis
Le langage C# intègre des attributs spéciaux comme System.AttributeUsageAttribute, qui décrit comment une classe d'attribut peut être utilisée ; System.Diagnostics.ConditionalAttribute, qui définit des méthodes conditionnelles ; et System.ObsoleteAttribute, qui identifie les membres obsolètes.
Attribut AttributeUsage
L'attribtu AttributeUsage décrit la manière d'utiliser une classe d'attribut. Toute classe décorée avec AttributeUsage doit hériter directement ou indirectement de System.Attribute, sinon une erreur de compilation se produit.
Attribut Conditional
L'attribut Conditional sert à définir des méthodes conditionnelles. Il détermine l'inclusion des appels en testant des symobles de compilation conditionnelle. Lorsque le symbole est défini, l'appel est inclus ; dans le cas contraire, il est omis.
Attribut Obsolete
L'attribut Obsolete marque les types ou membres qui ne sont plus recommandés. Les types ou membres annotés avec Obsolete génèrent des avertissements ou des erreurs durant la compilation.
Exemple de classe d'attribut personnalisé
using System;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class ValidationRuleAttribute : Attribute
{
public string RuleName { get; set; }
public int Priority { get; set; }
public ValidationRuleAttribute(string ruleName)
{
RuleName = ruleName;
Priority = 1;
}
}
[ValidationRule("BusinessLogicValidation", Priority = 5)]
public class BusinessProcessor
{
[ValidationRule("InputSanitization")]
public void ProcessData()
{
// Logique de traitement
}
}
Utilisation avec réflexion
using System;
using System.Reflection;
public static void AnalyzeCustomAttributes()
{
Type processorType = typeof(BusinessProcessor);
var classAttributes = processorType.GetCustomAttributes(typeof(ValidationRuleAttribute), false);
foreach (ValidationRuleAttribute attr in classAttributes)
{
Console.WriteLine($"Règle de validation: {attr.RuleName}, Priorité: {attr.Priority}");
}
MethodInfo methodInfo = processorType.GetMethod("ProcessData");
var methodAttributes = methodInfo.GetCustomAttributes(typeof(ValidationRuleAttribute), false);
foreach (ValidationRuleAttribute attr in methodAttributes)
{
Console.WriteLine($"Méthode validée: {attr.RuleName}");
}
}