Benutzerdefinierte Attribute (Komponentenerweiterungen für C++)
Benutzerdefinierte Attribute können Sie, um die Metadaten einer Schnittstelle, der Klasse oder Struktur, der Methode, des Parameters oder der Enumeration zu erweitern.
Alle Laufzeiten
Alle Laufzeiten unterstützen benutzerdefinierte Attribute.
Windows-Runtime
C++-/CXattribute unterstützen nur Eigenschaften, jedoch nicht schreiben Konstruktoren oder Methoden zu.
Anforderungen
Compileroption: /ZW
Common Language Runtime
Benutzerdefinierte Attribute können Sie die Metadaten eines verwalteten Elements erweitern.Weitere Informationen finden Sie unter Erweitern von Metadaten mithilfe von Attributen.
Hinweise
Die Informationen und die Syntax, die in diesem Thema dargestellt wird, wird bedeutet, um die Informationen abzulösen, die in Attribut dargestellt werden.
Sie können ein benutzerdefiniertes Attribut definieren, indem Sie einen Typ definieren und Attribute eine Basisklasse für den Typ ausführen und optional das AttributeUsageAttribute-Attribut.
Beispielsweise im Microsoft Transaction Server (Microsoft Transaction Server-Komponenten) 1,0, wurde Verhalten in Bezug auf Transaktionen, Synchronisierung, Lastenausgleich, usw. durch die benutzerdefinierte GUID angegeben, die in die Typbibliothek eingefügt wurde, indem Sie das benutzerdefinierte Attribut ODL verwendet.Daher kann ein Client eines MTS-Servers seine Eigenschaften durch Lesen der Typbibliothek bestimmen.In .NET Framework ist die Entsprechung der Typbibliothek Metadaten, und die Entsprechung der benutzerdefinierten Attribute ODL ist benutzerdefinierte Attribute.Auch die Typbibliothek zu lesen ist der Anwendung der Reflektion auf den Typen analog.
Weitere Informationen finden Sie unter
Informationen zum Signieren von Assemblys in Visual C++, finden Sie unter Assemblys mit starken Namen (Assemblysignierung) (C++/CLI).
Anforderungen
Compileroption: /clr
Beispiele
Beispiel
Das folgende Beispiel zeigt, wie ein benutzerdefiniertes Attribut definiert.
// 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 {};
Beispiel
Im folgenden Beispiel werden einige wichtige Funktionen von benutzerdefinierten Attributen.Beispielsweise ist dieses Beispiel eine allgemeine Verwendung benutzerdefinierter Attribute an: einen Server instanziieren, der auf den Clients kann sich vollständig beschreiben.
// 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);
}
}
Ausgabe
Beispiel
Der Object^-Typ ersetzt den varianten Datentyp.Im folgenden Beispiel wird ein benutzerdefiniertes Attribut, das ein Array von Object^ als Parameter akzeptiert.
Attributargumente müssen Kompilierzeitkonstanten sein; in den meisten Fällen sollten sie konstante Literale sein.
Siehe typeid (Komponentenerweiterungen für C++) für Informationen dazu, wie Sie einen Wert von System::Type von einem benutzerdefinierten Attributblock zurückgibt.
// 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 {};
Beispiel
Die Laufzeit erfordert, dass der öffentliche Teil der benutzerdefinierten Attributklasse serialisierbar sein muss.Wenn die Verwendung benutzerdefinierter Attribute erstellt, werden benannte Argumente des benutzerdefinierten Attributs auf Konstanten zur Kompilierungszeit beschränkt.(Wägen Sie es als Sequenz von Bits, die dem Klassenlayout in den Metadaten zugeordnet werden).
// 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 {};