X++ 屬性類別

備註

社區興趣小組現在已從 Yammer 轉移到 Microsoft Viva Engage。 若要加入 Viva Engage 社群並參與最新的討論,請填寫 [ 要求存取財務和營運 Viva Engage 社群 表單 」 ,並選擇您要加入的社群。

本文說明 X++ 中屬性的使用。

屬性是一種非抽象類別,從 SysAttribute 類別繼承而來。 屬性表示或儲存有關類型和方法的中繼資料。 你可以將屬性附加到類別、類別欄位、類別方法、介面或資料表。

對代理的處理器套用屬性,並用方法將處理器映射到這些目標。

建立屬性類別

屬性類別可以直接擴充 SysAttribute 類別,也可以擴充 SysAttribute 類別的任何子代。 你不能把 SysAttribute 類別當作屬性使用,因為它是宣告抽象的。 以下範例展示了你可以建立的普通屬性類別的宣告與設計。

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

使用屬性裝飾類別

下列範例顯示以上一個範例中指定的 PracticeAttribute 裝飾的類別和方法。 如果屬性的建構函式不採用任何參數,則參數的括弧是選擇性的。 屬性裝飾可以 [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.
}

如果後綴為 Attribute,您可以省略屬性名稱的後綴。 例如,您可以在上述範例中改用[Practice][PracticeAttribute]

屬性建構函式

你可以讓屬性類別在每次裝飾類別時,透過其建構子接收參數來儲存客製化的元資料。 建構函式的參數必須是基本類型的常值,例如 int、enumstr。 編譯器不會建構屬性類別的實例。 它會儲存屬性類別的名稱,以及其建構函式的常值。 因此,如果屬性建構子的邏輯會拋出異常,用該屬性裝飾類別並不會造成異常。 例外是在後面程序查看類別以查看其裝飾屬性時。 這個過程就是屬性被建構出來的時候。

命名慣例

所有屬性類別的名稱中都有後綴 Attribute屬性後綴是 Microsoft 推薦的命名慣例,但並非系統要求。 您可以在應用程式總管中選取類別,然後檢閱 [屬性] 視窗中的 Extends 屬性,以判斷類別是否直接從 SysAttribute延伸

系統過時屬性

系統提供數個屬性,包括 SysObsoleteAttribute 類別。 SysObsoleteAttribute 類別的其中一個用途是通知編譯器,如果在原始程式碼中呼叫特定方法,編譯應該會失敗。 編譯器會拒絕編譯,並顯示儲存在屬性使用此使用中的特定訊息。 SysObsoleteAttribute 類別也可用來通知編譯器發出警告訊息,而不是錯誤。

SysObsoleteAttribute 程式碼範例

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

中繼資料反射

您可以使用反映來尋找附加至類別的屬性 meta 資料。 用於屬性反射的類別如下:

  • DictClass 類別 – 適用於類別和介面。
  • DictMethod 類別 — 適用於類別、介面或資料表上的方法。

在前面的反射類上,反映屬性元數據的方法如下:

  • getAllAttributes 方法
  • getAttribute 方法
  • getAttributedClasses 方法
  • getAttributes 方法

備註

X++ 程式碼中沒有機制列出所有帶有特定屬性的方法或類別。 不過,因為 X++ 編譯器會將這些資訊記錄在交叉參考資料庫中,你可以從資料庫中挖掘這些資訊。

中繼資料反映程式碼範例

使用 DictMethod 類別來尋找裝飾方法的屬性的元資料值。 下列程式碼範例使用 SysEntryPointAttribute 類別作為屬性。 它接受方法名稱的參數值,以及包含方法之類別名稱的參數值。 parmChecked 方法是 SysEntryPointAttribute 類別特有的,且並非從其基底類別 SysAttribute 繼承而來。 每個屬性類別都可以有自己的中繼資料方法名稱。

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