Condividi tramite


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.

yd21828z.collapse_all(it-it,VS.110).gifRequisiti

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.

yd21828z.collapse_all(it-it,VS.110).gifNote

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

Per informazioni sugli assembly di firma in Visual C++, vedere Assembly con nome sicuro (firma degli assembly) (C++/CLI).

yd21828z.collapse_all(it-it,VS.110).gifRequisiti

Opzione del compilatore: /clr

yd21828z.collapse_all(it-it,VS.110).gifEsempi

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 {};

Vedere anche

Concetti

Estensioni componenti per le piattaforme runtime