【C#反射】Type的用法
Type属性的应用
Type type = typeof(MyClass); Console.Write("$类型名:{ type.Name}"); Console.Write("$类全名:{type.FullName}" ); Console.Write("$命名空间名:{ype.Namespace}"); Console.Write("$程序集名:{type.Assembly}" ); Console.Write("$模块名:{type.Module}" ); Console.Write("$基类名:{type.BaseType}" ); //C# 中,一个类型只能继承一个类型(基类型),使用实例的 Type.BaseType 属性,可以获取到此类型的基类型。 Console.Write("$是否类:{type.IsClass}"); Console.Write("$类的公共成员:{}"); MemberInfo[] memberInfos = type.GetMembers();//得到所有公共成员 foreach (var item in memberInfos) { Console.Write(string.Format("${ item.MemberType}:{ item}")); }
Type.MakeGenericType 动态创建泛型
// 先创建开放泛型 Type openType = typeof(List<>); // 再创建具象泛型 Type target = openType.MakeGenericType(new[] { typeof(string) }); // 最后创建泛型实例 List<string> result = (List<string>)Activator.CreateInstance(target);
c# Type.InvokeMember用法
public object InvokeMember(string, BindingFlags, Binder, object, object[]);
string:你所要调用的函数名
BindingFlags:你所要调用的函数的属性,可以组合
Binder:实例
object:调用该成员函数的实例
object[]:参数,
下面是msdn例子:
class MyType { Int32 myField; public MyType(ref Int32 x) { x *= 5; } public override String ToString() { return myField.ToString(); } public Int32 MyProp { get { return myField; } set { if (value < 1) throw new ArgumentOutOfRangeException("value", value, "value must be > 0"); myField = value; } } } class MyApp { static void Main() { Type t = typeof(MyType); // Create an instance of a type. Object[] args = new Object[] { 8 }; int ss = 5; Console.WriteLine("The value of x before the constructor is called is {0}.", args[0]); Object obj =(object) new MyType(ref ss); //也可以这样写 Object obj =t.InvokeMember(null,BindingFlags.CreateInstance, null, null, args); Console.WriteLine("Type: " + obj.GetType().ToString()); Console.WriteLine("The value of x after the constructor returns is {0}.", args[0]); // Read and write to a field. t.InvokeMember("myField",BindingFlags.Instance|BindingFlags.NonPublic| BindingFlags.SetField, null, obj, new Object[] { 5 }); Int32 v = (Int32)t.InvokeMember("myField",BindingFlags.NonPublic |BindingFlags.Instance | BindingFlags.GetField, null, obj, null); Console.WriteLine("myField: " + v); // Call a method. String s = (String)t.InvokeMember("ToString",BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod, null, obj, null); Console.WriteLine("ToString: " + s); // Read and write a property. First, attempt to assign an // invalid value; then assign a valid value; finally, get // the value. try { // Assign the value zero to MyProp. The Property Set // throws an exception, because zero is an invalid value. // InvokeMember catches the exception, and throws // TargetInvocationException. To discover the real cause // you must catch TargetInvocationException and examine // the inner exception. t.InvokeMember("MyProp", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty, null, obj, new Object[] { 0 }); } catch (TargetInvocationException e) { // If the property assignment failed for some unexpected // reason, rethrow the TargetInvocationException. if (e.InnerException.GetType() != typeof(ArgumentOutOfRangeException)) throw; Console.WriteLine("An invalid value was assigned to MyProp."); } t.InvokeMember("MyProp", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty, null, obj, new Object[] { 2 }); v = (Int32)t.InvokeMember("MyProp", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty, null, obj, null); Console.WriteLine("MyProp: " + v); } }
Type类 GETXXXX的方法
GetConstructor(), GetConstructors():返回ConstructorInfo
类型,用于取得该类的构造函数的信息
GetEvent(), GetEvents():返回EventInfo
类型,用于取得该类的事件的信息
GetField(), GetFields():返回FieldInfo
类型,用于取得该类的字段(成员变量)的信息
GetInterface(), GetInterfaces():返回InterfaceInfo
类型,用于取得该类实现的接口的信息
GetMember(), GetMembers():返回MemberInfo
类型,用于取得该类的所有成员的信息
GetMethod(), GetMethods():返回MethodInfo
类型,用于取得该类的方法的信息
GetProperty(), GetProperties():返回PropertyInfo
类型,用于取得该类的属性的信息
可以调用这些成员,其方式是调用Type的InvokeMember()
方法,或者调用MethodInfo
, PropertyInfo
和其他类的Invoke()
方法。
。。。。。。。
4、使用示例代码
1) 查看类中的构造方法
NewClassw nc = new NewClassw();
Type t = nc.GetType();
ConstructorInfo[] ci = t.GetConstructors(); //获取类的所有构造函数
foreach (ConstructorInfo c in ci) //遍历每一个构造函数
{
ParameterInfo[] ps = c.GetParameters(); //取出每个构造函数的所有参数
foreach (ParameterInfo pi in ps) //遍历并打印所该构造函数的所有参数
{
Console.Write(pi.ParameterType.ToString() + " " + pi.Name + ",");
}
Console.WriteLine();
}
2) 用构造函数动态创建对象
Type t = typeof(NewClassw);
Type[] pt = new Type[2];
pt[0] = typeof(string);
pt[1] = typeof(string);
//根据参数类型获取构造函数
ConstructorInfo ci = t.GetConstructor(pt);
//构造Object数组,作为构造函数的输入参数
object[] obj = new object[2]{"grayworm","hi.baidu.com/grayworm"};
//调用构造函数生成对象
object o = ci.Invoke(obj);
//调用生成的对象的方法测试是否对象生成成功
//((NewClassw)o).show();
3) 用Activator创建对象
Type t = typeof(NewClassw);
//构造函数的参数
object[] obj = new object[2] { "grayworm", "hi.baidu.com/grayworm" };
//用Activator的CreateInstance静态方法,生成新对象
object o = Activator.CreateInstance(t,"grayworm","hi.baidu.com/grayworm");
//((NewClassw)o).show();
4) 查看类中的属性
NewClassw nc = new NewClassw();
Type t = nc.GetType();
PropertyInfo[] pis = t.GetProperties();
foreach(PropertyInfo pi in pis)
{
Console.WriteLine(pi.Name);
}
5) 查看类中的public方法
NewClassw nc = new NewClassw();
Type t = nc.GetType();
MethodInfo[] mis = t.GetMethods();
foreach (MethodInfo mi in mis)
{
Console.WriteLine(mi.ReturnType+" "+mi.Name);
}
6) 查看类中的public字段
NewClassw nc = new NewClassw();
Type t = nc.GetType();
FieldInfo[] fis = t.GetFields();
foreach (FieldInfo fi in fis)
{
Console.WriteLine(fi.Name);
}
7) 用反射生成对象,并调用属性、方法和字段进行操作
NewClassw nc = new NewClassw(); Type t = nc.GetType(); object obj = Activator.CreateInstance(t); //取得ID字段 FieldInfo fi = t.GetField("ID"); //给ID字段赋值 fi.SetValue(obj, "k001"); //取得MyName属性 PropertyInfo pi1 = t.GetProperty("MyName"); //给MyName属性赋值 pi1.SetValue(obj, "grayworm", null); // null表示无参属性,有参是索引,必须传入一个实例, PropertyInfo pi2 = t.GetProperty("MyInfo"); pi2.SetValue(obj, "hi.baidu.com/grayworm", null); //取得show方法 MethodInfo mi = t.GetMethod("show"); //调用show方法 mi.Invoke(obj, null);
System.Type 创建实例
使用Type.InvokerMember可以调用类型的方法、属性。自然也可以通过调用类型的构造函数来创建一个类型的实例。
//直接调用无参构造函数 Object obj = typeof(Employee).InvokeMember(null, BindingFlags.CreateInstance, null, null, null);//BindingFlags.CreateInstance会调用构造函数 Employee employee =obj as Employee; employee.Say("InvokeMember default ctor"); // 使用带参数的构造函数 obj = typeof(Employee).InvokeMember(null, BindingFlags.CreateInstance, null, null, new object[] { "david" }); employee = obj as Employee; ((Employee)obj).Say("InvokeMember ctor with argument");