カスタム属性へのアクセス
更新 : 2007 年 11 月
プログラムの要素に属性を関連付けた後、リフレクションを使用して、属性の有無と属性値を照会できます。.NET Framework Version 1.0 および 1.1 では、カスタム属性は実行コンテキストでチェックされます。一方、.NET Framework Version 2.0 には、"リフレクションのみのコンテキスト" という新しい読み込みのコンテキストが用意されています。これを使用して、実行用に読み込むことができないコードをチェックできます。
リフレクションのみのコンテキスト
リフレクションのみのコンテキストに読み込まれたコードは実行できません。つまり、カスタム属性のインスタンスを作成できません。カスタム属性のインスタンスを作成するには、そのコンストラクタを実行する必要があります。リフレクションのみのコンテキストでカスタム属性を読み込んでチェックするには、CustomAttributeData クラスを使用します。このクラスのインスタンスは、CustomAttributeData.GetCustomAttributes 静的メソッドの適切なオーバーロードを使用して取得できます。方法 : リフレクションのみのコンテキストにアセンブリを読み込む を参照してください。
実行コンテキスト
実行コンテキストの属性を照会するための主なリフレクション メソッドには、System.Reflection.MemberInfo.GetCustomAttributes と System.Reflection.Assembly.GetCustomAttributes があります。
カスタム属性のアクセシビリティの確認は、カスタム属性がアタッチされているアセンブリに対して行われます。アクセシビリティを確認することは、カスタム属性がアタッチされているアセンブリ内の型に対するメソッドがカスタム属性のコンストラクタを呼び出すことができるかどうかを確認することと同じです。
GetCustomAttributes メソッド (Type, 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 オブジェクトの配列を返すのと同じです。クライアントがユーザー定義のカスタム属性型についての情報を探索できないようにするには、その型のメンバを非パブリックとして定義します。
リフレクションを使用してカスタム属性へのアクセス許可を取得する基本的な方法を次の例で示します。
Class Class1
Public Shared Sub Main()
Dim info As System.Reflection.MemberInfo = GetType(Class1)
Dim attributes() As Object = info.GetCustomAttributes(True)
For i As Integer = 0 To attributes.Length - 1
System.Console.WriteLine(attributes(i))
Next i
End Sub
End Class
class MyClass
{
public static void Main()
{
System.Reflection.MemberInfo info = typeof(MyClass);
object[] attributes = info.GetCustomAttributes(true);
for (int i = 0; i < attributes.Length; i++)
{
System.Console.WriteLine(attributes[i]);
}
}
}