カスタム属性へのアクセス
プログラムの要素に属性を関連付けた後、リフレクションを使用して、属性の有無と属性値を照会できます。 .NET Framework Version 1.0 および 1.1 では、カスタム属性は実行コンテキストでチェックされます。 一方、.NET Framework Version 2.0 には、"リフレクションのみのコンテキスト" という新しい読み込みのコンテキストが用意されています。これを使用して、実行用に読み込むことができないコードをチェックできます。
リフレクションのみのコンテキスト
リフレクションのみのコンテキストに読み込まれたコードは実行できません。 つまり、カスタム属性のインスタンスを作成できません。カスタム属性のインスタンスを作成するには、そのコンストラクターを実行する必要があります。 リフレクションのみのコンテキストでカスタム属性を読み込んでチェックするには、CustomAttributeData クラスを使用します。 このクラスのインスタンスは、CustomAttributeData.GetCustomAttributes 静的メソッドの適切なオーバーロードを使用して取得できます。 方法 : リフレクションのみのコンテキストにアセンブリを読み込む を参照してください。
実行コンテキスト
実行コンテキストの属性を照会するための主なリフレクション メソッドには、MemberInfo.GetCustomAttributes と Attribute.GetCustomAttributes があります。
カスタム属性のアクセシビリティの確認は、カスタム属性がアタッチされているアセンブリに対して行われます。 アクセシビリティを確認することは、カスタム属性がアタッチされているアセンブリ内の型に対するメソッドがカスタム属性のコンストラクターを呼び出すことができるかどうかを確認することと同じです。
Assembly.GetCustomAttributes(Boolean) のようなメソッドは、型引数の参照可能範囲とアクセシビリティを確認します。 ユーザー定義型を含むアセンブリ内のコードだけが、GetCustomAttributes を使用してその型のカスタム属性を取得できます。
代表的なカスタム属性のデザイン パターンを次の C# のコード例に示します。 この例は、ランタイム カスタム属性リフレクション モデルを示しています。
System.DLL
public class DescriptionAttribute : Attribute
{
}
System.Web.DLL
internal class MyDescriptionAttribute : DescriptionAttribute
{
}
public class LocalizationExtenderProvider
{
[MyDescriptionAttribute(...)]
public CultureInfo GetLanguage(...)
{
}
}
ランタイムが GetLanguage メソッドにアタッチされたパブリック カスタム属性型 DescriptionAttribute のカスタム属性の取得を試みる場合は、次のアクションを実行します。
ランタイムは、Type.GetCustomAttributes (type 型) への型引数 DescriptionAttribute がパブリックで、参照可能およびアクセス可能であることをチェックします。
DescriptionAttribute から派生したユーザー定義型 MyDescriptionAttribute が、GetLanguage() メソッドに DescriptionAttribute がアタッチされている System.Web.DLL アセンブリ内で参照可能であり、アクセス可能であることを確認します。
MyDescriptionAttribute のコンストラクターが、System.Web.DLL アセンブリ内で参照可能であり、アクセス可能であることを確認します。
カスタム属性パラメーターを持つ MyDescriptionAttribute のコンストラクターを呼び出し、呼び出し元に新しいオブジェクトを返します。
カスタム属性リフレクション モデルが、ユーザー定義型のインスタンスを、その型が定義されているアセンブリの外部にリークする場合があります。 これは、Type.GetMethods() のようなユーザー定義型のインスタンスを返すランタイム システム ライブラリ内のメンバーが、RuntimeMethodInfo オブジェクトの配列を返すのと同じです。 クライアントがユーザー定義のカスタム属性型についての情報を探索できないようにするには、その型のメンバーを非パブリックとして定義します。
リフレクションを使用してカスタム属性へのアクセス許可を取得する基本的な方法を次の例で示します。
Imports System
Public Class ExampleAttribute
Inherits Attribute
Private stringVal As String
Public Sub New()
stringVal = "This is the default string."
End Sub
Public Property StringValue() As String
Get
Return stringVal
End Get
Set(Value As String)
stringVal = Value
End Set
End Property
End Class
<Example(StringValue := "This is a string.")> _
Class Class1
Public Shared Sub Main()
Dim info As System.Reflection.MemberInfo = GetType(Class1)
For Each attrib As Object In info.GetCustomAttributes(true)
Console.WriteLine(attrib)
Next attrib
End Sub
End Class
using System;
public class ExampleAttribute : Attribute
{
private string stringVal;
public ExampleAttribute()
{
stringVal = "This is the default string.";
}
public string StringValue
{
get { return stringVal; }
set { stringVal = value; }
}
}
[Example(StringValue="This is a string.")]
class Class1
{
public static void Main()
{
System.Reflection.MemberInfo info = typeof(Class1);
foreach (object attrib in info.GetCustomAttributes(true))
{
Console.WriteLine(attrib);
}
}
}
using namespace System;
public ref class ExampleAttribute : Attribute
{
private:
String^ stringVal;
public:
ExampleAttribute()
{
stringVal = "This is the default string.";
}
property String^ StringValue
{
String^ get() { return stringVal; }
void set(String^ value) { stringVal = value; }
}
};
[Example(StringValue="This is a string.")]
public ref class Class1
{
public:
static void Main()
{
System::Reflection::MemberInfo^ info = Type::GetType("Class1");
for each (Object^ attrib in info->GetCustomAttributes(true))
{
Console::WriteLine(attrib);
}
}
};
int main()
{
Class1::Main();
}
参照
参照
MemberInfo.GetCustomAttributes