Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Note
Les groupes d’intérêt communautaire sont maintenant passés de Yammer à Microsoft Viva Engage. Pour participer à une communauté Viva Engage et participer aux dernières discussions, renseignez le formulaire Demander l’accès à la communauté Finance et Operations Viva Engage , puis choisissez la communauté que vous souhaitez rejoindre.
Cet article décrit l’utilisation d’attributs dans X++.
Un attribut est une classe non abstraite qui étend (hérite de) la classe SysAttribute . Les attributs représentent ou stockent des métadonnées sur les types et méthodes. Un attribut peut être attaché à une classe, à un champ de classe, à une méthode de classe, à une interface ou à une table.
Les attributs sont appliqués aux gestionnaires de délégués et de méthodes pour mapper les gestionnaires à ces cibles.
Création d’une classe d’attributs
Une classe d’attributs peut étendre directement la classe SysAttribute ou étendre n’importe quel descendant de la classe SysAttribute . La classe SysAttribute ne peut pas être utilisée comme attribut, car elle est déclarée abstraite. L’exemple suivant montre la déclaration et la conception d’une classe d’attribut ordinaire que vous pouvez créer.
public class PracticeAttribute extends SysAttribute
{
// Fields in the classDeclaration.
StartEnd startEndEnum;
str reason;
// Constructor.
public void new(StartEnd _startEndEnum, str _reason)
{
startEndEnum = _startEndEnum;
reason = _reason;
}
// Other methods can go here.
}
Décoration d’une classe avec un attribut
L’exemple suivant montre une classe et une méthode décorées avec le PracticeAttribute donné dans l’exemple précédent. Si le constructeur de l’attribut ne prend aucun paramètre, les parenthèses des paramètres sont facultatives. La décoration d’attribut peut être [AnotherAttribute] sans parenthèses.
[PracticeAttribute(StartEnd::End, "Use the RegularClass class at the end.")]
public class RegularClass
{
[PracticeAttribute(Startend::Start, "Use the rehearse method at the start.")]
public int rehearse()
{
// Logic goes here.
}
// More fields and methods belong here.
}
Vous pouvez omettre le suffixe du nom d’attribut si le suffixe est Attribute. Par exemple, vous pouvez utiliser [Practice] à la place [PracticeAttribute] dans l’exemple précédent.
Constructeurs d’attributs
Vous pouvez autoriser votre classe d’attributs à stocker des métadonnées personnalisées chaque fois qu’elle est utilisée pour décorer une classe, en ayant son constructeur prendre des paramètres. Les paramètres du constructeur doivent être des littéraux des types primitifs, tels que int,enum ou str. Le compilateur ne construit pas une instance de la classe d’attributs. Il stocke le nom de la classe d’attributs, ainsi que les valeurs littérales de son constructeur. Par conséquent, si la logique d’un constructeur d’attribut lève une exception, l’exception n’est pas trouvée en décorant une classe avec l’attribut. L’exception est trouvée ultérieurement lorsqu’un processus examine une classe pour voir l’attribut avec qui il est décoré. C’est-à-dire lorsque l’attribut est construit.
Conventions d’affectation de noms
Toutes les classes d’attribut ont l’attribut de suffixe dans leur nom. Le suffixe d’attribut est la convention de nom que nous recommandons, mais il ne s’agit pas d’une exigence système. Vous pouvez déterminer si une classe s’étend directement à partir de SysAttribute en sélectionnant la classe dans l’Explorateur d’applications et en examinant la propriété Extends dans la fenêtre Propriétés .
SysObsoleteAttribute
Le système fournit plusieurs attributs, notamment la classe SysObsoleteAttribute . L’une des utilisations de la classe SysObsoleteAttribute consiste à informer le compilateur que la compilation doit échouer si une méthode particulière est appelée dans le code source. Le compilateur rejette la compilation et affiche le message spécifique stocké dans cette utilisation de l’attribut. La classe SysObsoleteAttribute peut également être utilisée pour avertir le compilateur d’émettre des messages d’avertissement au lieu d’erreurs.
Exemple de code SysObsoleteAttribute
[SysObsoleteAttribute("The Automobile class might have faster performance.", false)]
class Bicycle
{
// Members of the Bicycle class go here.
}
Réflexion sur les métadonnées
Vous utilisez la réflexion pour rechercher les métadonnées d’attribut attachées à une classe. Les classes à utiliser pour la réflexion d’attribut sont les suivantes :
- Classe DictClass : pour les classes et les interfaces.
- Classe DictMethod : pour les méthodes sur les classes, les interfaces ou les tables.
Dans les classes de réflexion précédentes, les méthodes permettant de réfléchir aux métadonnées d’attribut sont les suivantes :
- getAllAttributes , méthode
- getAttribute , méthode
- méthode getAttributedClasses
- getAttributes , méthode
Note
Il n’existe aucun mécanisme permettant de répertorier toutes les méthodes ou classes qui sont ornées d’un attribut particulier à partir du code X++. Toutefois, étant donné que le compilateur X++ enregistre ces informations dans la base de données de référence croisée, les informations peuvent être extraites à partir de là.
Exemple de code de réflexion des métadonnées
Vous utilisez la classe DictMethod pour rechercher la valeur de métadonnées d’un attribut qui est une décoration sur une méthode. L’exemple de code suivant utilise la classe SysEntryPointAttribute comme attribut. Il accepte vos valeurs de paramètre pour le nom de la méthode et pour le nom de la classe qui contient la méthode. La méthode parmChecked est particulière à la classe SysEntryPointAttribute , et elle n’est pas héritée de sa classe de base SysAttribute. Chaque classe d’attribut peut avoir son propre nom de méthode pour ses métadonnées.
static public int MetadataOfSysEntryPointAttributeOnMethod
(
str _sNameOfClass,
str _sNameOfMethod
)
{
// Return Values:
// 0 == Has the attribute, its metadata value is false;
// 1 == Has the attribute, its metadata value is true;
// 2 == The method lacks the SysEntryPointAttribute.
int nReturnValue = -1,
nClassId;
boolean boolParmChecked;
DictMethod dm;
Object attributeAsObject;
SysEntryPointAttribute sepAttribute;
Global::info("Starting AttributeReflection"
+ " ::MetadataOfSysEntryPointAttributeOnMethod ....");
Global::info(strFmt
("Parameters are: _sNameOfClass = %1 , _sNameOfMethod = %2 .",
_sNameOfClass, _sNameOfMethod)
);
nClassId = Global::className2Id(_sNameOfClass);
dm = new DictMethod
(UtilElementType::ClassInstanceMethod,
nClassId,
_sNameOfMethod
);
attributeAsObject = dm.getAttribute("SysEntryPointAttribute");
if (attributeAsObject is SysEntryPointAttribute)
{
sepAttribute = attributeAsObject as SysEntryPointAttribute;
boolParmChecked = sepAttribute.parmChecked();
if (boolParmChecked)
nReturnValue = 1;
else
nReturnValue = 0;
Global::info(
strFmt("Return value is %1.",
nReturnValue)
);
}
else
{
nReturnValue = 2;
Global::error("Object is not a SysEntryPointAttribute??");
}
return nReturnValue;
}
/*** Output displayed in the Infolog.
Message (05:03:22 pm)
Starting AttributeReflection ::MetadataOfSysEntryPointAttributeOnMethod ....
Parameters are: _sNameOfClass = CustCustomerService , _sNameOfMethod = create .
Return value is 1.
***/
/**************
// Simple AOT > Jobs job to run the method.
static void AttributeReflection33Job(Args _args)
{
AttributeReflection::MetadataOfSysEntryPointAttributeOnMethod
("CustCustomerService", "create");
}
**************/