TL;DR;
GetAttribute
で見つかったタイミング。
ちなみにキャッシュはされない。
属性(Attribute)とは
C#…といか.NETは強力なメタプログラミングが可能な言語(フレームワーク)です。
各クラスやメソッドなどにリフレクション情報が含まれていて、この情報から、メソッドの名前や属するクラス、継承関係などを取得することができます。
また、そのリフレクション情報を拡張するための機能としてカスタム属性という機能があります。
例えばHogeAttribute
というAttributeを継承したクラスを定義し、これを付与したいクラスやメソッドなどの直前に[Hoge()]
と付加します。括弧の中に引数を渡すこともできます。
カスタム属性の取得方法
Attribute[] attrs = typeof(TargetClass).GetCustomAttributes(true);
HogeAttribute hoge = attrs.FirstOrDefault(a => a is HogeAttribute);
// または
HogeAttribute hoge = Attribute.GetAttribute(typeof(TargetClass), typeof(HogeAttribute)) as HogeAttribute;
ジェネリックに対応していないので、T GetAttribute<T>(this Type t) : where T : Attribute
みたいな拡張クラスを用意して使うことが多いかと思います。
確認
class TestAttribute : Attribute
{
public TestAttribute(string msg)
{
Console.WriteLine($"\tCREATED ATTRIBUTE INSTANCE {msg}");
}
}
[Test("INSTANCE")]
class InstanceClass
{
public InstanceClass() { }
}
[Test("STATIC")]
static class StaticClass
{
public static void Method() { }
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("InstanceClass new");
new InstanceClass();
Console.WriteLine("StaticClass Call");
StaticClass.Method();
Console.WriteLine("InstanceClass TypeInfo");
var c = typeof(InstanceClass);
Console.WriteLine("StaticClass TypeInfo");
var s = typeof(StaticClass);
Console.WriteLine("InstanceClass GetAttribute");
c.GetCustomAttributes(true);
Console.WriteLine("StaticClass GetAttribbute");
s.GetCustomAttributes(true);
Console.WriteLine("InstanceClass GetAttribute 2");
c.GetCustomAttributes(true);
Console.WriteLine("StaticClass GetAttribbute 2");
s.GetCustomAttributes(true);
}
}
Output
InstanceClass new
StaticClass Call
InstanceClass TypeInfo
StaticClass TypeInfo
InstanceClass GetAttribute
CREATED ATTRIBUTE INSTANCE INSTANCE
StaticClass GetAttribbute
CREATED ATTRIBUTE INSTANCE STATIC
InstanceClass GetAttribute 2
CREATED ATTRIBUTE INSTANCE INSTANCE
StaticClass GetAttribbute 2
CREATED ATTRIBUTE INSTANCE STATIC
GetCustomAttributes
の時点でTestAttributeのコンストラクタが呼ばれていることがわかります。
また、二回目のGetCustomAttributes
の後にもコンストラクタがよばれていることが確認できました。