備註
社區興趣小組現在已從 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、enum 或 str。 編譯器不會建構屬性類別的實例。 它會儲存屬性類別的名稱,以及其建構函式的常值。 因此,如果屬性建構子的邏輯會拋出異常,用該屬性裝飾類別並不會造成異常。 例外是在後面程序查看類別以查看其裝飾屬性時。 這個過程就是屬性被建構出來的時候。
命名慣例
所有屬性類別的名稱中都有後綴 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");
}
**************/