型の宣言の情報を表すクラスです。
型 | フィールド | 内容 |
---|---|---|
Type[] | EmptyTypes | Type型の空の配列 |
char | Delimiter | |
object | Missing | |
型 | プロパティ | 内容 |
---|---|---|
string | FullName | 型の完全修飾名 (fully qualified name) |
bool | IsArray | 型が配列であるならば、true。int[]はtrueだが、ArrayやIEnumerable<T>はfalseとなる Remarks - Type.IsArray Property (System) | Microsoft Learn |
bool | IsClass | 型がクラスまたはデリゲートならば、true |
Type type = typeof(int); string s1 = type.Namespace; // "System" string s2 = type.Name; // "Int32" string s3 = type.FullName; // "System.Int32" string s4 = type.AssemblyQualifiedName; // "System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
戻り値の型 | メソッド | 機能 |
---|---|---|
Type | MakeArrayType() | 1次元配列として表されるTypeオブジェクトを得られる |
Type | MakeByRefType() | ref修飾子を付けて渡されるときのTypeオブジェクトを得られる
つまりType.GetType("System.Object&")として得られるTypeを、typeof(System.Object).MakeByRefType()で得られる |
たとえば次のような型があるとすると、
public class MyClass { private int field1; public int field2; private void Method1(int a, int b) { } public void Method2(int a, int b) { } public int Property1 { get; } }
この型のTypeから、メンバの情報を取得できます。
public MemberInfo[] GetMembers()Type.GetMembers メソッド (System) | Microsoft Learn
返されるメンバは、アルファベット順や宣言順などの特定の順番とはなりません。Remarks - Type.GetMembers Method (System)
Type type = typeof(MyClass); MemberInfo[] memberInfos = type.GetMembers(); // すべてのパブリック メンバ ConstructorInfo[] ConstructorInfos = type.GetConstructors(); // すべてのパブリック コンストラクタ FieldInfo[] fieldInfos = type.GetFields(); // すべてのパブリック フィールド MethodInfo[] methodInfos = type.GetMethods(); // すべてのパブリック メソッド PropertyInfo[] propertyInfos = type.GetProperties(); // すべてのパブリック プロパティ EventInfo[] eventInfo= type.GetEvents(); // すべてのパブリック イベント Console.Write(fieldInfos[0].Name); // field2
実装または継承されている、すべてのインターフェイスを取得できます。
public abstract Type[] GetInterfaces ();
typeof(int).GetInterfaces() // [0]: {Name = "IComparable" FullName = "System.IComparable"} // [1]: {Name = "IFormattable" FullName = "System.IFormattable"} // [2]: {Name = "IConvertible" FullName = "System.IConvertible"} // [3]: {Name = "IComparable`1" FullName = "System.IComparable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"} // [4]: {Name = "IEquatable`1" FullName = "System.IEquatable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"}
バインディング制約を指定して、コンストラクタを検索できます。
[System.Runtime.InteropServices.ComVisible(true)]
public System.Reflection.ConstructorInfo GetConstructor (
System.Reflection.BindingFlags bindingAttr, // バインディング制約
System.Reflection.Binder binder,
Type[] types,
System.Reflection.ParameterModifier[] modifiers
);
GetConstructor(BindingFlags, Binder, Type[], ParameterModifier[]) - Type.GetConstructor メソッド (System) | Microsoft Learn
Type type = typeof(MyClass); // 引数のないコンストラクタの呼び出し ConstructorInfo info1 = type.GetConstructor( BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null); MyClass myClass1 = (MyClass)info1.Invoke(null); // 引数が(int, double)であるコンストラクタの呼び出し ConstructorInfo info2 = type.GetConstrctor( BindingFlags.Instance | BindingFlags.Public, null, new[] { typeof(int), typeof(double) }, null); MyClass myClass2 = (MyClass)info2.Invoke(new object[] { 1, 2.0 });
Activator.CreateInstance()ならば、直接インスタンスを作成できます。
public static object CreateInstance (
Type type,
System.Reflection.BindingFlags bindingAttr, // バインディング制約
System.Reflection.Binder binder,
object[] args,
System.Globalization.CultureInfo culture
);
CreateInstance(Type, BindingFlags, Binder, Object[], CultureInfo) - Activator.CreateInstance メソッド (System) | Microsoft Learn
// 引数のないコンストラクタの呼び出し MyClass obj1 = (MyClass)Activator.CreateInstance( type, BindingFlags.Instance | BindingFlags.Public, null, null, CultureInfo.InvariantCulture); // 引数のあるコンストラクタの呼び出し MyClass obj2 = (MyClass)Activator.CreateInstance( type, BindingFlags.Instance | BindingFlags.Public, null, new object[] { 1, 2.0 }, CultureInfo.InvariantCulture);
バインディング制約を指定して、フィールドを検索できます。
public abstract System.Reflection.FieldInfo GetField ( string name, // フィールドの名前 System.Reflection.BindingFlags bindingAttr // バインディング制約 );GetField(String, BindingFlags) - Type.GetField メソッド (System) | Microsoft Learn
取得時にBindingFlags.NonPublicを指定すると非パブリックなメンバの情報も取得でき、これを介すとprivateなメンバへもアクセスできます。そして設定はFieldInfo.SetValue()、取得はFieldInfo.GetValue()で行えます。
このとき対象がインスタンスのフィールドならばそのインスタンスを、クラスのそれならばnullを渡します。
MyClass obj = new MyClass(); // obj.field1 = 1; // error CS0122: 'MyClass.field1' はアクセスできない保護レベルになっています Type type = typeof(MyClass); FieldInfo field1 = type.GetField("field1", BindingFlags.NonPublic | BindingFlags.Instance); field1.SetValue(obj, 1); // ok int value = (int)field1.GetValue(obj);
バインディング制約は、アクセス対象の修飾子によって下表のように指定します。
アクセス対象の修飾子 | バインディング制約 |
---|---|
private |
BindingFlags.NonPublic | BindingFlags.Instance |
private static |
BindingFlags.NonPublic | BindingFlags.Static |
一致するフィールドが存在しなければ、nullが返されます。
アクセスできない型はそのTypeを得られないため、この方法でもアクセスできません。
バインディング制約を指定して、プロパティを検索できます。
public System.Reflection.PropertyInfo GetProperty (
string name,
System.Reflection.BindingFlags bindingAttr // バインディング制約
);
GetProperty(String, BindingFlags) - Type.GetProperty メソッド (System) | Microsoft Learn
バインディング制約を指定して、メソッドを検索できます。
public System.Reflection.MethodInfo GetMethod (
string name,
System.Reflection.BindingFlags bindingAttr // バインディング制約
);
GetMethod(String, BindingFlags) - Type.GetMethod メソッド (System) | Microsoft Learn
Type type = typeof(MyClass); MethodInfo method1 = type.GetMethod("Method1", BindingFlags.NonPublic | BindingFlags.Instance); MyClass obj = new MyClass(); method1.Invoke(obj, new object[] { 1, 2 });
メソッドに同じバインディング制約のオーバーロードがあるときは、引数の型も指定しないと「あいまいな一致が見つかりました。」としてAmbiguousMatchExceptionが投げられます。
public System.Reflection.MethodInfo GetMethod ( string name, System.Reflection.BindingFlags bindingAttr, // バインディング制約 System.Reflection.Binder binder, // プロパティの一式を定義し、バインディングを有効にするオブジェクト Type[] types, // 引数の数、並び、型を表す System.Reflection.ParameterModifier[] modifiers // typesの要素の属性 );
MethodInfo method1 = type.GetMethod( "Method1", BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(int), typeof(int) }, null);
静的なメソッドを呼び出すならば、GetMethod()のbindingAttrにBindingFlags.Staticを指定します。
public object Invoke ( object obj, // メソッドまたはコンストラクタを呼び出すクラスのオブジェクト object[] parameters // メソッドまたはコンストラクタへ渡す引数のリスト );Invoke(Object, Object[]) - MethodBase.Invoke メソッド (System.Reflection) | Microsoft Learn
呼び出すのが静的なメソッドならば、objは無視されます。引数がないならばparametersはnullとします。あるならば引数と同数の長さの配列を渡さないと、「パラメーター カウントが一致しません。」としてTargetParameterCountExceptionが投げられます。
メソッドの引数にrefやoutなどのパラメータ修飾子が付けられているならば、parametersに渡す引数をローカルで保持しておきます。c# - How to pass a parameter as a reference with MethodInfo.Invoke - Stack Overflow
int a = 1;
object[] parameters = new object[] { a };
method1.Invoke(obj, parameters);
// 値をコピーして渡しているためaには作用しないが、parameters[0]から結果を得られる
このように呼び出したメソッドからはすべての例外がTargetInvocationExceptionで投げられるため、実際の例外はそれのInnerExceptionで確認します。TargetInvocationException クラス (System.Reflection) | Microsoft Learn
ジェネリック メソッドの定義に置き換えたMethodInfoを得ることで、それを呼び出せます。MethodInfo.MakeGenericMethod(Type[]) Method (System.Reflection) | Microsoft Learn
たとえばメソッドが、
public class MyClass { public void Method<T>(T val) {} }
のように定義されているならば、次のように呼び出せます。
Type type = typeof(MyClass); MethodInfo method = type.GetMethod("Method"); MyClass obj = new MyClass(); // method.Invoke(obj, new object[] { 1 }); // InvalidOperationException「ContainsGenericParameters が true に設定されている型またはメソッド上で遅延バインディング操作を実行することはできません。」 // obj.Method<int>(1); の呼び出し MethodInfo genericMethod1 = method.MakeGenericMethod(typeof(int)); genericMethod1.Invoke(obj, new object[] { 1 }); // obj.Method<string>("a"); の呼び出し MethodInfo genericMethod2 = method.MakeGenericMethod(typeof(string)); genericMethod2.Invoke(obj, new object[] { "a" });