Déclaration des attributs personnalisés (RTTI)
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.
Sommaire
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.