用户定义的特性(C++ 组件扩展)

自定义特性可扩展接口的元数据、选件类或结构、方法、参数或枚举。

所有运行时

所有运行时支持自定义特性。

Windows 运行时

C++/CX 特性只支持属性,但是,属性不是构造函数或方法。

yd21828z.collapse_all(zh-cn,VS.110).gif要求

编译器选项:/ZW

公共语言运行时

自定义特性使您可以扩展托管组件的元数据。 有关更多信息,请参见利用特性扩展元数据

yd21828z.collapse_all(zh-cn,VS.110).gif备注

本主题和语法存在的信息被视为取代在 特性存在的信息。

通过定义类型并将 Attribute 该类型的基类和选项适用 AttributeUsageAttribute 属性定义自定义特性。

例如,在 Microsoft Transaction Server (MTS) 1.0,有关事务的行为,同步,负载平衡,依此类推通过自定义 GUID 指定了插入到类型库可以使用 ODL 自定义特性。 因此,MTS 服务器的客户端可通过读取类型确定其属性库。 在 .NET Framework,模拟的类型库是元数据,并且,模拟的 ODL 自定义属性是自定义特性。 此外,读取类型库类似于使用类型上的反射。

有关更多信息,请参见

有关在 Visual C++ 中的程序集进行签名的信息,请参见 强名称程序集(程序集签名)(C++/CLI)

yd21828z.collapse_all(zh-cn,VS.110).gif要求

编译器选项:/clr

yd21828z.collapse_all(zh-cn,VS.110).gif示例

示例

下面的示例演示如何定义自定义特性。

// 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

  
  
  
  
  
  

示例

System::object^类型替换不同的数据类型。 下面的示例定义了一个数组 System::object^作为参数的自定义特性。

特性参数必须为编译时常数;在大多数情况下,它们应是常数的文本。

有关如何的 typeid(C++ 组件扩展) 返回 System::Type 的值的信息从自定义特性的块。

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

请参见

概念

适用于运行时平台的组件扩展