X++ attribuut klassen

In dit artikel wordt het gebruik van attributen in X++ beschreven.

Een attribuut is een niet-abstracte klasse die de SysAttribut-klasse uitbreidt (erft). Kenmerken vertegenwoordigen of slaan metagegevens over typen en methoden op. Je kunt een attribuut koppelen aan een klasse, een klasseveld, een klassemethode, een interface of een tabel.

Pas attributen toe op de handlers van delegates en methoden om de handlers aan die doelen toe te wijzen.

Een kenmerkklasse maken

Een attribuutklasse kan de klasse SysAttribute rechtstreeks uitbreiden, of het kan een afstammeling van de klasse SysAttribute uitbreiden. Je kunt de SysAttribut-klasse niet als attribuut gebruiken omdat deze abstract is verklaard. Het volgende voorbeeld toont de verklaring en het ontwerp van een gewone attribuutklasse die je kunt maken.

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.
}

Een klas versieren met een eigenschap

In het volgende voorbeeld ziet u een klasse en een methode die zijn versierd met het kenmerk PracticeCertificate dat in het vorige voorbeeld is gegeven. Als de constructor van het attribuut geen parameters gebruikt, zijn de haakjes voor de parameters optioneel. De attribuutversiering zou zonder haakjes kunnen staan [AnotherAttribute] .

[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.
}

U kunt het achtervoegsel van de kenmerknaam weglaten als het achtervoegsel .Attribute U kunt bijvoorbeeld in plaats daarvan [Practice] in het voorgaande voorbeeld gebruiken[PracticeAttribute].

Attribute constructors

Je kunt je attribuutklasse inschakelen om op maat gemaakte metadata op te slaan telkens wanneer hij een klasse decoreert, door de constructor parameters te laten nemen. De parameters voor de constructeur moeten letterlijke waarden zijn van de primitieve typen, zoals int,enum of str. De compiler construeert geen instantie van de attribuutklasse. Het slaat de naam van de attribuutklasse op, plus de letterlijke waarden voor de constructor. Daarom, als de logica in een attribuutconstructor een uitzondering zou geven, veroorzaakt het decoreren van een klasse met het attribuut de uitzondering niet. De uitzondering wordt later gevonden wanneer een proces naar een klasse kijkt om te zien met welk attribuut deze is versierd. Dat proces is wanneer het attribuut wordt geconstrueerd.

Naming conventions

Alle kenmerkklassen hebben het achtervoegsel Attribute in hun naam. Het Attribuut-achtervoegsel is de naamconventie die Microsoft aanbeveelt, maar het is geen systeemvereiste. U kunt bepalen of een klasse zich rechtstreeks vanuit SysAttributeuitstrekt door de klasse te selecteren in de Toepassingsverkenner en de eigenschap Extend in het venster Eigenschappen te bekijken.

SysObsoleteAttribute

Het systeem biedt verschillende attributen, waaronder de klasse SysObsoleteAttribute . Een van de toepassingen van de klasse SysObsoleteAttribute is om de compiler te laten weten dat de compilatie zou moeten mislukken als een bepaalde methode in de broncode wordt aangeroepen. De compiler weigert de compilatie en geeft het specifieke bericht weer dat is opgeslagen in dit gebruik van het attribuut. De klasse SysObsoleteAttribute kan ook worden gebruikt om de compiler op de hoogte te stellen dat er waarschuwingsberichten moeten worden uitgegeven in plaats van fouten.

Voorbeeld van SysObsoleteAttribute-code

[SysObsoleteAttribute("The Automobile class might have faster performance.", false)]
class Bicycle
{
    // Members of the Bicycle class go here.
}

Metadata reflection

Je gebruikt reflectie om de metagegevens van het kenmerk te vinden die aan een klas zijn gekoppeld. De klassen die moeten worden gebruikt voor attribuutreflectie zijn als volgt:

  • DictClass class – Voor klassen en interfaces.
  • DictMethod class – Voor methoden op klassen, interfaces of tabellen.

Voor de vorige reflectieklassen zijn de methoden voor het reflecteren op attribuutmetagegevens als volgt:

  • getAllAttributes method
  • getAttribute method
  • getAttributedClasses method
  • getAttributes method

Note

Er is geen mechanisme om alle methoden of klassen te vermelden die zijn versierd met een bepaald attribuut uit X++-code. Omdat de X++-compiler deze informatie echter in de kruisreferentiedatabase opneemt, kun je deze informatie daar ontlenen.

Voorbeeld van metadata-reflectiecode

Gebruik de DictMethod-klasse om de metadatawaarde te vinden van een attribuut dat een methode versiert. In het volgende codevoorbeeld wordt de klasse SysEntryPointAttribute als kenmerk gebruikt. Het accepteert uw parameterwaarden voor de naam van de methode en voor de naam van de klasse die de methode bevat. De parmChecked-methode is specifiek voor de SysEntryPointAttribut-klasse en wordt niet geërfd van de basisklasse SysAttribute. Elke attribuutklasse kan een eigen methodenaam hebben voor de metagegevens.

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");
}
**************/