C# の属性、リフレクション
- 属性とは、以下のように、メタデータを追加する仕組みのことです。
[assembly: AssemblyTitle("")] // AssemblyInfo.cs 内 [Serializable] Class MySerializableClass { }
以下のように独自の属性を作ることもできます。
public class BugFixAttribute : System.Attribute { int BugID; String Comment, Date, Programmer; public BugFixAttribute( int bugID, String programmer, String date ) { this.BugID = bugID; this.Programmer = programmer; this.Date = date; } } [BugFixAttribute( 121, "Jack", "2008/11/24", Comment = "Hello World" )] //!<属性の付加 public class MyTest { // ... 何かコード }
public static void Main() { MyTest t = new MyTest(); System.Reflection.MemberInfo inf = typeof(MyMath); Object[] attributes = inf.GetCustomAttributes(typeof(BugFixAttribute), false); foreach(Object attribute in attributes) //!<属性を調べてプロパティを表示 { BugFixAttribute a = (BugFixAttribute)attribute; Console.WriteLine("BugID={0}, Programmer={1}, Date={2}, Comment={3}", a.BugID, a.Programmer, a.Date, a.Comment); } }
- リフレクションを使うことで、以下のようにアセンブリ内の、メソッドやプロパティなどの情報を探索することができます。
public class MyTest { public static void Main() { Assembly a = Assembly.Load("Mscorlib"); //!< アセンブリの動的な読み込み Type[] types = a.GetTypes(); foreach (Type t in types) { Console.WriteLine("Type={0}", t); foreach (MemberInfo i in t.GetMembers()) Console.WriteLine("{0}={1}", i, i.MemberType); } } }
- 実行時での、動的なメソッドの呼び出し (実行時バインディング)は以下のように行います。
public class MyTest { public static void Main() { Type typeMath = Type.Get("Sysmte.Math"); // Math は static クラスなのでインスタンスは不必要 // Object obj = Activator.CreateInstance(typeMath); // 引数の型の指定 Type[] typeParams = new Type[1]; typeParams[0] = Type.GetType("Sysmte.Double"); // 関数の探索 MethodInfo infoCos = typeMath.GetMethod("Cos", typeParams); // 引数のインスタンスの作成 Object[] parameters = new Object[1]; parameters[0] = 45.0 * 3.14 / 180; // 関数の呼び出し Object val = infoCos.Invoke(typeMath, parameters); Console.WriteLine("コサイン45度は {0}", val); } }