反射
前言:
首先我们在学习反射之前我们首先要知道:什么是反射?反射可以做什么事情?有什么样子的优势以及劣势?
反射可以做什么?
- 动态的访问一个程序集中的元数据,比如像一些属性,完整的类型名称以及成员名称这样的构造,甚至是一些特性也都是可以获取的!
- 使用元数据,在运行时动态的调用一个类型的成员,而不是在执行编译是绑定。
使用反射访问元数据的例子
DateTime dateTime=new DateTime();
//获取类型
Type type = dateTime.GetType();
//类型的名称
string TypeName = type.Name;
//是不是public的
bool isPublic = type.IsPublic;
//类型的基类是什么
Type baseType = type.BaseType;
//获取该类型所实现的接口
Type[] types = type.GetInterfaces();
//类型是定义在那个程序集中的
System.Reflection.Assembly assembly = type.Assembly;
//获取所有的属性
System.Reflection.PropertyInfo[] propertyInfos = type.GetProperties();
//获取所有的方法
System.Reflection.MethodInfo[] methodInfos = type.GetMethods();
//获取所有的字段
System.Reflection.FieldInfo[] fieldInfos = type.GetFields();
//获取所有的特性
System.Collections.Generic.IEnumerable<Attribute> enumerable = type.GetCustomAttributes();
通过上面这种方式我们就可以实现对一个类型的所有的属性的访问以及使用。
那么怎样基于反射创建一个实例对象呢?
//基于反射创建实例对象
object v = type.Assembly.CreateInstance(type.Name);
怎样基于反射调用方法呢?
//基于反射调用方法
type.GetMethod("xxx").Invoke(参数);
我的看法:
其实反射准确的来说是一种能力,正是因为他的这种能力,所有很多框架的底层都是使用的反射。首先我们还是对比来看,在java中我们要使用反射的话首先要获取类的模板,怎么获取呢?两种方式:1.类名.Class 2.实例对象.getClass(),在c#中就是上面的方式,其实这更像是一种父与子的关系,首先我们通常都是使用的实例对象,也就是我们new出来的对象,放在堆里面的对象,我们知道,每一个类都有一个类模板存储在栈中,我们通过反射其实就是通过这个模板来进行操作,但是这种反射有一个问题就是性能不是特别的好,原因有以下几点:
- Method#invoke 方法会对参数做封装和解封操作
- 需要检查方法可见性
- 需要校验参数
- 反射方法难以内联
所以我们在使用反射的时候还是要慎用!