使用者定義屬性 (C++ 元件擴充功能)
自訂屬性可讓您擴充介面的中繼資料、類別或結構、方法、參數或列舉型別。
所有執行階段
所有的執行階段支援自訂屬性。
Windows 執行階段
C++/CX 屬性僅支援屬性,不過,沒有屬性 (Attribute) 建構函式或方法。
需求
編譯器選項: /ZW
Common Language Runtime
自訂屬性可以讓您擴充 Managed 項目的中繼資料。如需詳細資訊,請參閱使用屬性擴充中繼資料。
備註
本主題和語法提出的資訊視為代替在 屬性提出的資訊。
您可以定義型別和執行 Attribute 型別的基底類別和選擇性套用 AttributeUsageAttribute 屬性定義自訂屬性。
例如,在 Microsoft Transaction Server (MTS) 版,有關交易的行為,同步,負載平衡,依此類推將自訂 GUID 指定的插入至型別程式庫使用 ODL 自訂屬性。因此, MTS 伺服器的用戶端可以讀取型別判斷其特性程式庫。在 .NET Framework 中,這個型別程式庫的類比是中繼資料,因此, ODL 自訂屬性的類比是自訂屬性。此外,將型別程式庫類似於使用型別上的反應。
如需詳細資訊,請參閱:
如需 Visual C++ 的簽署組件的詳細資訊,請參閱 強式名稱組件 (組件簽署) (C++/CLI)。
需求
編譯器選項: /clr
範例
範例
下列範例顯示如何定義自訂屬性。
// user_defined_attributes.cpp
// compile with: /clr /c
using namespace System;
[AttributeUsage(AttributeTargets::All)]
ref struct Attr : public Attribute {
Attr(bool i){}
Attr(){}
};
[Attr]
ref class MyClass {};
範例
下列範例說明自訂屬性的一些重要功能。例如,這個範例顯示自訂屬性的常見用法:具現化可完整描述自己給用戶端的伺服器。
// extending_metadata_b.cpp
// compile with: /clr
using namespace System;
using namespace System::Reflection;
public enum class Access { Read, Write, Execute };
// Defining the Job attribute:
[AttributeUsage(AttributeTargets::Class, AllowMultiple=true )]
public ref class Job : Attribute {
public:
property int Priority {
void set( int value ) { m_Priority = value; }
int get() { return m_Priority; }
}
// You can overload constructors to specify Job attribute in different ways
Job() { m_Access = Access::Read; }
Job( Access a ) { m_Access = a; }
Access m_Access;
protected:
int m_Priority;
};
interface struct IService {
void Run();
};
// Using the Job attribute:
// Here we specify that QueryService is to be read only with a priority of 2.
// To prevent namespace collisions, all custom attributes implicitly
// end with "Attribute".
[Job( Access::Read, Priority=2 )]
ref struct QueryService : public IService {
virtual void Run() {}
};
// Because we said AllowMultiple=true, we can add multiple attributes
[Job(Access::Read, Priority=1)]
[Job(Access::Write, Priority=3)]
ref struct StatsGenerator : public IService {
virtual void Run( ) {}
};
int main() {
IService ^ pIS;
QueryService ^ pQS = gcnew QueryService;
StatsGenerator ^ pSG = gcnew StatsGenerator;
// use QueryService
pIS = safe_cast<IService ^>( pQS );
// use StatsGenerator
pIS = safe_cast<IService ^>( pSG );
// Reflection
MemberInfo ^ pMI = pIS->GetType();
array <Object ^ > ^ pObjs = pMI->GetCustomAttributes(false);
// We can now quickly and easily view custom attributes for an
// Object through Reflection */
for( int i = 0; i < pObjs->Length; i++ ) {
Console::Write("Service Priority = ");
Console::WriteLine(static_cast<Job^>(pObjs[i])->Priority);
Console::Write("Service Access = ");
Console::WriteLine(static_cast<Job^>(pObjs[i])->m_Access);
}
}
Output
範例
Object^型別取代不同的資料型別。下列範例會定義取得陣列 Object^做為參數的自訂屬性。
屬性引數必須是編譯時期常數;在大部分情況下,應該是常數常值。
如需 typeid (C++ 元件擴充功能) 如何傳回 System::Type 值的資訊從自訂屬性 (Attribute) 區塊的。
// extending_metadata_e.cpp
// compile with: /clr /c
using namespace System;
[AttributeUsage(AttributeTargets::Class | AttributeTargets::Method)]
public ref class AnotherAttr : public Attribute {
public:
AnotherAttr(array<Object^>^) {}
array<Object^>^ var1;
};
// applying the attribute
[ AnotherAttr( gcnew array<Object ^> { 3.14159, "pi" }, var1 = gcnew array<Object ^> { "a", "b" } ) ]
public ref class SomeClass {};
範例
執行階段需要自訂屬性類別的 public 區段必須可序列化。當建立自訂屬性,名為自訂屬性的引數僅限於編譯時期常數。(想像為位元序列附加至在中繼資料類別配置)。
// extending_metadata_f.cpp
// compile with: /clr /c
using namespace System;
ref struct abc {};
[AttributeUsage( AttributeTargets::All )]
ref struct A : Attribute {
A( Type^ ) {}
A( String ^ ) {}
A( int ) {}
};
[A( abc::typeid )]
ref struct B {};