Attributi definiti dall'utente (Estensioni del componente C++)
Gli attributi personalizzati consentono di estendere i metadati di un'interfaccia, una classe o una struttura, un metodo, un parametro, o un'enumerazione.
Tutti i runtime
Tutti i runtime supportano attributi personalizzati.
Windows Runtime
Gli attributi di C++/CX supportano solo le proprietà, ma non i costruttori di attributo o metodi.
Requisiti
Opzione del compilatore: /ZW
Common Language Runtime
Gli attributi personalizzati consentono di estendere i metadati di un elemento gestito.Per ulteriori informazioni, vedere Estensione di metadati mediante attributi.
Note
Le informazioni e la sintassi fornite in questo argomento sono progettate per sostituire le informazioni fornite in attributo.
È possibile definire un attributo personalizzato definizione di un tipo e aggiungere a Attribute una classe base del tipo ed eventualmente applicando l'attributo AttributeUsageAttribute.
Ad esempio, nella transazione (MTS) server 1,0, il comportamento rispetto alle transazioni, la sincronizzazione, bilanciamento del carico di Microsoft e altri, è stato specificato con personalizzato GUID inserita nella libreria dei tipi tramite l'attributo personalizzato ODL.Pertanto, un client a un server MTS potrebbe determinare caratteristiche leggendo la libreria dei tipi.In .NET Framework, il valore della libreria dei tipi è di metadati e il valore dell'attributo personalizzato ODL è attributi personalizzati.Inoltre, leggere la libreria dei tipi è analoga a tramite la reflection nei tipi.
Per ulteriori informazioni, vedere
Destinazioni degli attributi (Estensioni del componente C++)
Tipi di parametri degli attributi (Estensioni del componente C++)
Per informazioni sugli assembly di firma in Visual C++, vedere Assembly con nome sicuro (firma degli assembly) (C++/CLI).
Requisiti
Opzione del compilatore: /clr
Esempi
Esempio
Il seguente codice di esempio mostra come definire un attributo personalizzato.
// 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 {};
Esempio
L'esempio seguente illustra alcune importanti funzionalità di attributi personalizzati.Ad esempio, in questo esempio viene illustrato un utilizzo comune di attributi personalizzati: creare un'istanza di un server che può essere autodescriversi ai client.
// 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
Esempio
Il tipo di Object^ sostituisce il tipo di dati variant.L'esempio seguente definisce un attributo personalizzato che accetta una matrice di Object^ come parametri.
Gli argomenti di attributo devono essere costanti in fase di compilazione; nella maggior parte dei casi, devono essere valori letterali costanti.
Vedere typeid (Estensioni del componente C++) per informazioni su come restituire un valore di System::Type da un blocco di attributi personalizzati.
// 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 {};
Esempio
Il runtime richiede che la parte pubblica della classe di attributi personalizzati devono essere serializzabili.Nel creare attributi personalizzati, gli argomenti predefiniti dell'attributo personalizzato sono limitati alle costanti in fase di compilazione.(Considerarla come sequenza di bit aggiunti al layout della classe nei metadati.)
// 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 {};