反射基本内容
一、程序集
①动态加载程序集
Assembly ams = Assembly.LoadFile(@"xxx.dll");
②获取指定类型所在的程序集,一般获取之后是为了获取反射其它类型
typeof(TestAttribute).Assembly
③获取程序集所在的Type
//1.0获取所有类型
ams.GetTypes()
//2.0获取所有public类型
ams.GetExportedTypes()
//获取指定类型的Type,如以下获取Person的,参数是完全限定名称(命名空间(项目右击属性查看,一般和程序集名相同)+类名)
Type typePerson = ams.GetType("PersonNameSPace.Person");
二、动态调用方法
①获取 //会全部获取出来,包括继承object的,属性(本质就是方法) MethodInfo[] methods = typePerson.GetMethods(); for (int i = 0; i < methods.Length; i++) { Console.WriteLine(methods[i].Name); } ②获取指定的并且调用 var methodSayHi= typePerson.GetMethod("SayHi"); //第一个参数是类型对象,第二个是方法参数; //调用就跟委托一样Invoke methodSayHi.Invoke(Activator.CreateInstance(typePerson), null); Console.ReadKey();
三、方法参数,构造函数有多个或者重载怎么办?
//需要在获取方法的时候指定参数有哪些类型,类型顺序一定要一致 var methodSayHi= typePerson.GetMethod("SayHi",new Type[]{typeof(string)}); methodSayHi.Invoke(Activator.CreateInstance(typePerson), new object[] { "xxx" });
四、为属性赋值
var nameProp= typePerson.GetProperty("Name"); var obj=Activator.CreateInstance(typePerson); nameProp.SetValue(obj, "123");//设置值 Console.WriteLine(nameProp.GetValue(obj));//获取值
五、创建对象
实现1:调用无参构造函数:object obj= Activator.CreateInstance(typePerson); 实现2:调用有参构造函数 1、通过type类型获取指定的构造函数,参数是构造函数的参数的type类型数组(按顺序) 构造函数: public Person(int age,string name) { this.Age = age; this.Name = name; } 2、获取此构造函数并且调用 ConstructorInfo ctor= typePerson.GetConstructor(new Type[] {typeof(int),typeof(string)}); object obj= ctor.Invoke(new object[] { 19, "XXX" }); //获取之后就能调用方法等操作了,比如: 调用方法: MethodInfo info = typePerson.GetMethod("SayHi"); info.Invoke(obj,null);
六、获取非public的方法,就把sayhi方法改为私有的再测试
Person p = new Person(); Type typePerson = typeof(Person); MethodInfo method = typePerson.GetMethod("SayHi", BindingFlags.NonPublic | BindingFlags.Instance); method.Invoke(Activator.CreateInstance(typePerson), null); Console.WriteLine("ok"); Console.ReadKey();
七、lambda构造创建类
反射的性能比较低的,我们可以用lambda构造来代替或者构造函数调用得到一个对象。时间仓促,不做演示了:
直接copy真实项目的一段代码留下:
var cmd = type.GetCustomAttributes(typeof(LanduCmdAttribute), false).OfType<LanduCmdAttribute>().Select(p => p.Cmd).Single(); var ctor = type.GetConstructors().Single(); //REF:https://stackoverflow.com/a/6582310/2430943 var func = (Func<LanduPacket>)Expression.Lambda(typeof(Func<LanduPacket>), Expression.New(ctor)).Compile(); dic[cmd] = func;