Déclaration des attributs personnalisés (RTTI)

De Appmethod Topics
Aller à : navigation, rechercher

Remonter à Attributs - Index


Cette rubrique décrit les méthodes de base utilisées pour créer des attributs personnalisés, les décisions de conception appropriées pour les classes d'attributs et les cas d'utilisation généraux.

Déclaration d'un attribut

Un attribut est un type de classe simple. Pour déclarer votre propre attribut personnalisé, vous devez le dériver d'une classe prédéfinie spéciale : System.TCustomAttribute :

type
    MyCustomAttribute = class(TCustomAttribute)
    end;

MyCustomAttribute peut ensuite être utilisé pour annoter tout type ou tout membre d'un type (tel que classe, enregistrement ou interface) :

type
   [MyCustomAttribute]
   TSpecialInteger = type integer;

   TSomeClass = class
        [MyCustomAttribute]
        procedure Work;
   end;

Sachez que la classe d'attribut déclarée ne doit pas être déclarée en tant que classe abstraite et ne doit pas contenir des méthodes abstraites. Bien que le compilateur vous permet d'utiliser ces attributs pour l'annotation, le binaire construit ne les inclura pas dans les informations RTTI émises.

Les noms d'attribut qui se terminent par 'Attribute' sont tout simplement tronqués

Supposons que vous définissiez deux sous-classes TCustomAttribute avec le même préfixe, mais que l'une a le suffixe 'Attribute', comme dans :

  • MyCustom
  • MyCustomAttribute

La classe ayant le suffixe 'Attribute' (MyCustomAttribute) est toujours utilisée, et la classe ayant le nom le plus court (MyCustom) devient inaccessible.

L'extrait de code suivant montre ce problème. On pourrait s'attendre à ce que la sous-classe Test de TCustomAttribute soit appliquée, mais du fait de la troncature de nom implicite, c'est TestAttribute qui est appliqué lorsque [Test] ou [TestAttribute] est utilisé.

type
  // To check ambigious names
  TestAttribute = class(TCustomAttribute)
  end;

  // Becomes unaccessible
  Test = class(TCustomAttribute)
  end;

  [Test] // Resolves to TestAttribute at run time
  TAmbigiousClass = class
  end;

Constructeurs dans les attributs

Normalement, un attribut est conçu pour transporter des informations supplémentaires qui peuvent être interrogées à l'exécution. Pour autoriser la spécification d'informations personnalisées pour la classe d'attributs, vous devez déclarer des constructeurs :

type
    AttributeWithConstructor = class(TCustomAttribute)
    public
        constructor Create(const ASomeText: String);
   end;

qui peuvent ensuite être utilisés comme suit :

 type
   [AttributeWithConstructor('Added text value!')]
   TRecord = record
        FField: Integer;
   end;

La résolution de la méthode fonctionne aussi pour les attributs, ce qui signifie que vous pouvez définir des constructeurs surchargés dans l'attribut personnalisé. Déclarez seulement des constructeurs qui acceptent des valeurs constantes, et pas des valeurs out ou var. Cela se produit hors d'une restriction de base dans la façon dont les attributs fonctionnent et est traité plus en détail dans la rubrique Annotation des types et des membres de types.

Voir aussi