ユーザー定義属性 (C++/CLI および C++/CX)User-Defined Attributes (C++/CLI and C++/CX)

C++/CLI とC++/CX では、インターフェイス、クラス、構造体、メソッド、パラメーター、または列挙型のメタデータを拡張するプラットフォーム固有の属性を作成できます。C++/CLI and C++/CX enable you to create platform-specific attributes that extend the metadata of an interface, class or structure, method, parameter, or enumeration. これらの属性は、標準 C++ 属性とは異なります。These attributes are distinct from the standard C++ attributes.

Windows ランタイムWindows Runtime

C++/CX 属性は、プロパティに適用できますが、コンストラクターまたはメソッドには適用できません。You can apply C++/CX attributes to properties, but not to constructors or methods.

要件Requirements

コンパイラ オプション: /ZWCompiler option: /ZW

共通言語ランタイムCommon Language Runtime

このトピックに示されている情報と構文は、「属性」に示されている情報に優先します。The information and syntax presented in this topic is meant to supersede the information presented in attribute.

型を定義し、Attribute をその型の基底クラスにすることで、カスタム属性を定義できます。必要に応じて AttributeUsageAttribute 属性を適用できます。You can define a custom attribute by defining a type and making Attribute a base class for the type and optionally applying the AttributeUsageAttribute attribute.

詳細については次を参照してください:For more information, see:

Visual C++ でのアセンブリへの署名については、「厳密名アセンブリ (アセンブリ署名) (C++/CLI)」を参照してください。For information on signing assemblies in Visual C++, see Strong Name Assemblies (Assembly Signing) (C++/CLI).

要件Requirements

コンパイラ オプション: /clrCompiler option: /clr

使用例Examples

次の例では、カスタム属性を定義する方法を示します。The following sample shows how to define a custom attribute.

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

次の例では、カスタム属性のいくつかの重要な機能を示します。The following example illustrates some important features of custom attributes. たとえば、この例では、カスタム属性の一般的な使用方法を示しています (クライアントに対して自身を完全に記述できるサーバーをインスタンス化します)。For example, this example shows a common usage of the custom attributes: instantiating a server that can fully describe itself to clients.

// 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);
   }
}
Service Priority = 0

Service Access = Write

Service Priority = 3

Service Access = Write

Service Priority = 1

Service Access = Read

Object^ 型によって、バリアント データ型が置換されます。 次の例では、Object^ の配列をパラメーターとして受け取るカスタム属性を定義します。The following example defines a custom attribute that takes an array of Object^ as parameters.

属性の引数はコンパイル時の定数である必要があります。ほとんどの場合、それらは定数リテラルになります。Attribute arguments must be compile-time constants; in most cases, they should be constant literals.

カスタム属性ブロックから System::Type の値を返す方法については、typeid を参照してください。See typeid for information on how to return a value of System::Type from a custom attribute block.

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

ランタイムでは、カスタム属性クラスのパブリック部分がシリアル化可能である必要があります。The runtime requires that the public part of the custom attribute class must be serializable. カスタム属性を作成する場合、カスタム属性の名前付き引数はコンパイル時の定数に限定されますWhen authoring custom attributes, named arguments of your custom attribute are limited to compile-time constants. (メタデータのクラスのレイアウトに追加される一連のビットと考えてください)。(Think of it as a sequence of bits appended to your class layout in the metadata.)

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

関連項目See also

.NET および UWP でのコンポーネント拡張Component Extensions for .NET and UWP