反射是.Net Framework提供的一个帮助类库,可以访问DLL和EXE的MetaData (描述数据的数据) ,使用它,可以在代码中将对具体类型的依赖转化成为字符串的依赖实现程序解耦。
MetaData | DLL | exe | pdb |
---|---|---|---|
DLL和EXE的描述文件 | 应用程序扩展、动态库 | 可执行程序 | 调试文件,供vs工具使用 |
- 加载dll到反射实例(命名空间+类名),使用时缺少加载的DLL的依赖项或者不存在的DLL会报错
Assembly assemly = Assembly.Load("`nameSpace.class`");
- 获取模块信息、程序及类型数组集合、获取类型下的方法集合
assemly.GetModules();
assemly.GetTypes();
assemly.GetTypes()[0].GetMethods();
- 加载类型并创建实例
Type type = assemly.GetType("Class");
//调用无参构造函数创建一个运行对象
object instance = Activator.CreateInstance(type);
//调用有参构造函数(按顺序)创建一个运行对象
object instance1 = Activator.CreateInstance(type,new object[] { "parmeter"});
- 调用方法
//加载类型
Type testType = assemly.GetType("Class");
//构造对象
object oTest = Activator.CreateInstance(testType);
//获取指定函数,函数参数类型,有重载的情况可以指定类型
MethodInfo method = testType.GetMethod("methods",new Type[] {"typeof(int)});
//调用函数
method.Invoke(oTest, null);
//获取方法参数
method.GetParameters()
//获取方法返回值
method.ReturnParameter
//调用泛型方法
Type genericType = assemly.GetType("GenericMethod");
object oGeneric = Activator.CreateInstance(genericType);
//获取方法
MethodInfo method = genericType.GetMethod("Show");
//指定方法参数类型
MethodInfo methodNew = method.MakeGenericMethod(typeof(int), typeof(string), typeof(int));
//调用函数
methodNew.Invoke(oGeneric, new object[] { 1, "jeck", 0 });
- 调用私有方法,反射会破坏类的访问性
//调用私有方法,其实没啥意义
MethodInfo mthod = testType.GetMethod("method4", BindingFlags.Instance | BindingFlags.NonPublic);
mthod.Invoke(oTest,null);
- 操作属性
//获取类型
Type type = typeof(Class);
object instance = Activator.CreateInstance(type);
//获取所有的属性集合并开始遍历
foreach (var item in type.GetProperties())
{
//获取属性名
var name = item.Name;
//动态设置对象instance的属性的值
item.SetValue(instance, "oVal");
//获取当前属性值
item.GetValue(oPeople);
}
//获取所有的字段集合并开始遍历
foreach (var item in type.GetFields())
{
var name = item.Name; //获取字段名
item.SetValue(instance, "str"); //动态设置对象instance的字段的值
item.GetValue(oPeople); //获取当前字段的值
}
//调用泛型(有几个参数就在类型后加`3,代表3个参数)
Type genericType = assemly.GetType("namespace.GenericClass`3");
//指定类型
Type genericNewType = genericType.MakeGenericType(typeof(int), typeof(string), typeof(Program));
//创建一个运行时对象
object oGeneric = Activator.CreateInstance(genericNewType);
反射能给我们在工作中很大的帮助,各种不同的组合使用方式能达到不同的目的效果,例如
1、动态创建对象,降低程序耦合性,避开编译器的检查
2、反射+配置文件+简单工厂 = IOC
3、反射+方法 =MVC
4、反射+属性 =ORM
这只是在某种层面抽象出来的一种说法,IOC MVC ORM这些成熟的框架技术,远远不止这么简单,只是在一部分的实现思想上采用了反射
机制,当然反射也是存在弊端的,例如常被人诟病的性能问题,其实可以使用加入一些缓存优化的策略去解决它。
如果您看完了,有可能写的不好,但还是请随手点个赞作为鼓励吧,谢谢