共用方式為


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屬性尾碼是我們建議的名稱慣例,但不是系統需求。 您可以在應用程式總管中選取類別,然後檢閱 [屬性] 視窗中的 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");
}
**************/