リフレクションによる属性へのアクセス (C# プログラミング ガイド)

更新 : 2007 年 11 月

カスタム属性を定義してソース コードで使用できたとしても、その情報を取得し、それに基づいて処理を実行する手段がなくては、価値のある機能とはいえません。C# では、リフレクション システムを使用して、カスタム属性で定義された情報を取得できます。ここで重要となるメソッドは GetCustomAttributes です。このメソッドは、ソース コードの属性に対応するオブジェクトの配列を実行時に返します。このメソッドには、オーバーロードされたバージョンがいくつかあります。詳細については、「Attribute」を参照してください。

[Author("H. Ackerman", version = 1.1)]
class SampleClass

上の属性宣言は、概念的には下の式と同等です。

Author anonymousAuthorObject = new Author("H. Ackerman");
anonymousAuthorObject.version = 1.1;

ただし、SampleClass に対して属性を問い合わせるまで、コードは実行されません。SampleClass に対して GetCustomAttributes を呼び出すと、Author オブジェクトが生成されて、上記のように初期化されます。クラスに他の属性がある場合は、他の属性オブジェクトが同じように作成されます。作成後、GetCustomAttributes は、配列内の Author オブジェクトとその他の属性オブジェクトを返します。この配列に対して反復処理を行うことで、各配列要素の種類に基づいて適用された属性を特定し、属性オブジェクトから情報を取得できます。

使用例

完全な例を次に示します。この例では、カスタム属性を定義し、いくつかのエンティティに適用し、リフレクションを使って情報を取得しています。

[System.AttributeUsage(System.AttributeTargets.Class |
                       System.AttributeTargets.Struct,
                       AllowMultiple = true)  // multiuse attribute
]
public class Author : System.Attribute
{
    string name;
    public double version;

    public Author(string name)
    {
        this.name = name;
        version = 1.0;  // Default value
    }

    public string GetName()
    {
        return name;
    }
}

[Author("H. Ackerman")]
private class FirstClass
{
    // ...
}

// No Author attribute
private class SecondClass
{
    // ...
}

[Author("H. Ackerman"), Author("M. Knott", version = 2.0)]
private class ThirdClass
{
    // ...
}

class TestAuthorAttribute
{
    static void Main()
    {
        PrintAuthorInfo(typeof(FirstClass));
        PrintAuthorInfo(typeof(SecondClass));
        PrintAuthorInfo(typeof(ThirdClass));
    }

    private static void PrintAuthorInfo(System.Type t)
    {
        System.Console.WriteLine("Author information for {0}", t);
        System.Attribute[] attrs = System.Attribute.GetCustomAttributes(t);  // reflection

        foreach (System.Attribute attr in attrs)
        {
            if (attr is Author)
            {
                Author a = (Author)attr;
                System.Console.WriteLine("   {0}, version {1:f}", a.GetName(), a.version);
            }
        }
    }
}
/* Output:
    Author information for FirstClass
       H. Ackerman, version 1.00
    Author information for SecondClass
    Author information for ThirdClass
       M. Knott, version 2.00
       H. Ackerman, version 1.00
*/

参照

概念

C# プログラミング ガイド

参照

リフレクション (C# プログラミング ガイド)

属性 (C# プログラミング ガイド)

属性の使用 (C# プログラミング ガイド)

属性の対象の明確化 (C# プログラミング ガイド)

カスタム属性の作成 (C# プログラミング ガイド)

System.Reflection

Attribute