1.什么是反射
反射对程序集的元数据进行检查的过程。
1.1.访问程序集中类型的元数据,对编译过后的文件进行分析。
1.2.可以通过反射动态调用方法。
1.3.可以反编译泛型中包含的类型。
反射常常和泛型一起使用,泛型相当于提供了一个可动态指定类型的容器,然后通过反射就可以动态的反编译出来指定的特定类型并可以执行相应的方法或者获取相应的属性的值。
2.使用反射访问方法
我们常常有这样的编程需要,编写一个更加灵活,更加通用的程序。他可以按照规定无线扩展的公用方法,在传统使用继承关系常常是比较麻烦实现的。这时我们使用泛型和反射就可以很快的编写出这样一个公用的方法。
如下:我们通过获取一个方法的名称这是一个字符串类型,然后通过反射动态调用这个方法,把执行的结果返回回来:
var dbtype = "SqlServerMonitor"; //这是我们要调用的方法名称 Object[] obj = new Object[] { ConnectionString, DbType };//实例化Object类型里面的两个参数作为实例化该类的构造函数的参数。 Type type = this.GetType();//获取本类类型 var t = Activator.CreateInstance(type, obj); //通过本类的类型和够着函数的参数,实例化了一个新的对象。 MethodInfo method = type.GetMethod(dbtype, BindingFlags.Instance | BindingFlags.Public);//获取该类的所调用方法的索引 DBDetail db = (DBDetail)method.Invoke(t, null);//执行调用方法,然后把调用的值返回。
这里我们就完成了一个已知函数的方法名称,然后动态调用该方法,把执行的值返回的功能。解释:在使用这种方法时候需要注意的三点:
第一、在反射调用的时候只能新构造一个对象,然后通过新对象调用方法,在实例化新对象的时候需要传入该类构造函数的参数。
第二、这里单独使用Object[]来存放够着函数的参数,注意这里的参数顺序和类中构造函数的顺序一致哈。
第三、在需要使用反射调用的方法需要时Public类型,应为private和protected不能通过BindingFlags动态获取其索引的。
有了这样的方法我们就可以执行晚期绑定,也即是在执行时而不是编译时定义要调用的代码。
3.使用反射访问泛型类型
使用反射动态访问泛型类型,这个普遍使用,比如我们要写一个公用的输出类型。编辑一个公用的输出类型可以作为通用的输出方法,可以吧需要输出的内容都可以通过这个方法进行页面打印。
如下:就一个一个结合泛型的通用输出方法:
static void consoleResult<T>(T t) { var properties = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public);//获取T的类型,然后通过BindingFlags获取类型的Public属性 foreach (var p in properties) { var result = p.Name+": "+p.GetValue(t, null).ToString();//循环该properties输出每一项的name和相应的值。 Console.WriteLine(result);//进行页面终端输出。 } }
这样的方法就可以把符合规定的类型通过一个公用方法进行结果输出。解释:使用这样的方法注意一点就是使用的属性需要时Public类型
4.小结
利用反射,可以很大灵活性编写需要的程序,可以执行所谓的晚期绑定,也就是在执行时而不是编译时定义要调用的代码。反射可用来动态编程,但是比较与静态链接(编译时链接)、定义好代码,反射执行的速度要慢得多。但是熟练的掌握反射你在动态语言的Python和ruby都会有很好的理解了。
原文:http://blog.csdn.net/scalzdp/article/details/25054299