Compartir a través de


Atributos definidos por el usuario (Extensiones de componentes de C++)

Los atributos personalizados permiten ampliar los metadatos de una interfaz, clase o estructura, un método, un parámetro, o una enumeración.

Todos los runtimes

Todos los atributos personalizados admiten runtimes.

Windows en tiempo de ejecución

Los atributos de C++/CX sólo admiten propiedades, pero no constructores de atributos o métodos.

Requisitos

Opción del compilador: /ZW

Common Language Runtime

Los atributos personalizados permiten extender los metadatos de un elemento administrado. Para obtener más información, vea Extender metadatos mediante atributos.

Comentarios

La información y la sintaxis presentadas en este tema se ha diseñado para reemplazar la información mostrada en atributo.

Puede definir un atributo personalizado definiendo un tipo y crear Attribute una clase base para el tipo y opcionalmente aplicando el atributo de AttributeUsageAttribute .

Por ejemplo, en Microsoft Transaction Server (MTS) 1,0, comportamiento con respecto a las transacciones, sincronización, equilibrio de carga, etc. se especificado mediante GUID personalizado incrustado en la biblioteca de tipos mediante el atributo personalizado ODL. Por consiguiente, un cliente de un servidor de MTS podría determinar sus características leyendo la biblioteca de tipos. En .NET Framework, el analógico de la biblioteca de tipos es metadatos, y el analógico de atributo personalizado ODL es atributos personalizados. También, leer la biblioteca de tipos es análogo a utilizar la reflexión en tipos.

Para obtener más información, vea

Para obtener información sobre la firma de ensamblados en Visual C++, vea Ensamblados de nombre seguro (Firma de ensamblados) (C++/CLI).

Requisitos

Opción del compilador: /clr

Ejemplos

Ejemplo

El ejemplo siguiente se muestra cómo definir un atributo personalizado.

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

Ejemplo

El ejemplo siguiente muestra algunas características importantes de atributos personalizados. Por ejemplo, este ejemplo muestra un uso común de los atributos personalizados: crear instancias de un servidor que puede describirse totalmente a los clientes.

// 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);
   }
}

Resultados

  
  
  
  
  
  

Ejemplo

El tipo de Object^ reemplaza el tipo de datos variant. El ejemplo siguiente define un atributo personalizado que toma una matriz de Object^ como parámetros.

Los argumentos de atributo deben ser constantes en tiempo de compilación; en la mayoría de los casos, deben ser literales constantes.

Vea typeid (Extensiones de componentes de C++) para obtener información sobre cómo devolver un valor de System::Type de un bloque de atributos personalizados.

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

Ejemplo

El tiempo de ejecución requiere que la parte pública de la clase de atributos personalizada debe ser serializable. Al crear atributos personalizados, los argumentos con nombre del atributo personalizado se limitan a constantes en tiempo de compilación. (Piense en él como una secuencia de bits anexado al diseño de la clase de metadatos).

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

Vea también

Conceptos

Extensiones de componentes para plataformas de tiempo de ejecución