什么是反射?
正常情况下高级语言通过编译器编译,生成exe、dll等,再通过cli/jit处理被机器语言识别(二进制)。exe文件DLL文件通过反编译可查看到文件中有metadata和IL。
Metadata:是记录类中每一个元素;是一个数据清单。
反射:Reflection命名空间,是微软提供一个帮助类库;读取元数据,使用元数据中对应的元素。
一般情况下通过new对象,然后在调用方法等。new对象调用构造函数
反射使用:
第一步:动态加载dll
Assembly.load("xxx")
Assembly.loadfrom("xxx.dll")
Assembly.loadfile("c:/xxx/xxx.dll")全路径
第二步:获取type
Type t=Assembly.load("xxx").gettype("命令空间.库名")
第三步:转换类型
object o=activator.createInstance(t)在声明时确定类型
获取到的是object类型,需要转换成需要的类型,可以通过强制类型转化、as 转化、dynamic
类型 l=(类型)o;
类型 l=o as 类型;
dynamic o=activator.createInstance(t)在调用是确定类型
第四步:调用方法
o.show();
另一种
MethodInfo method = type.GetMethod("Show");//调用方法 Object[] objPar = new Object[] { "OK" };参数数组 object test = method.Invoke(o, objPar);//Invoke调用方法,带objetct类型,和参数数据
不了解这2种区别在哪里?
除了一般的方法外还有泛型类和泛型方法的反射。
动态加载dll-》获取type(库名,带几个泛型参数就标注 ~3)-》makegenerictype-》转换类型调用方法
Type t=Assembly.load("xxx").gettype("命令空间.库名~3")
Type tt=t.makegenerictype(new type[] {typeof(int),typeof(string),typeof(datetime)})指定类型
var o=activator.createInstance(tt)
methodInfo mm=tt.GetMethod(“show”)
mm.invoke(o,new object[]{123,"",datetime.now})
反射除了可以获得方法外,还可以获得字段和属性。
type t=typeof(student)
object o=activator.createInstance(t)
foreach(var p in t.getproperties())
{
if(p.name.equals("id"))
{
p.setvalue(o,123)
}
}
字段类似,properties改成fields
获取值就将set改为get 如:p.getvalue(o)