前言:使用反射也有几年了,可是一直以为,反这个概念很抽象,今天有时间就来总结下这个知识点。架构
一、为何须要反射:spa
最初使用反射的时候,做为小菜老是不理解,既然能够经过new 一个对象的方式获得对象,而后经过对象去调用属性和方法,那么为何还须要反射去调用呢?后来使用多了发现这就是一个先绑定仍是后绑定的问题,不少初使用反射的开发人员一般都会有相似这种疑虑:既然在开发时就可以写好代码,干吗还放到运行期去作,不光繁琐,并且效率也受影响。博主以为主要是适用性的问题,若是你的系统没有那么高的扩展性和灵活性要求,你大可没必要考虑反射。但在架构设计时,不少东西都须要考虑复用性,而且在某些特定的场景下你得不到具体的类时,你就必须用到反射。博主总结了下本身使用过的反射场景:架构设计
(1)有时不知道具体的类型,能够经过dll去获得类的对象;设计
(2)某些特殊方法,传过来的是泛型类,须要经过反射处理某些特殊的业务;code
(3)通用方法DataTable和List<T>的相互转化时须要用到反射;对象
二、如何使用反射:blog
(1)反射dll获得类成员:开发
在一个未知的dll里面有一个Person类get
public class Person { private string address; private string email; public string Name { set; get; } public int Age { set; get; } public void SayHello() { Console.WriteLine("你好"); } public static string MystaticPro { set; get; } public static void MyStatic() { Console.WriteLine("我是static方法"); } }
经过反射dll获得Person类string
static void Main(string[] args) {
//经过类名称获得类型
//var assembly = Assembly.Load("Ewin.Client.Web");//参数为程序集的名称
//var oType = assembly.GetType("Ewin.Client.Web.Controllers." + strType);
//反射dll var strDllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "dll\\ReflectorDLL.dll"); var oAssembly = Assembly.LoadFile(strDllPath); var lstTypes = oAssembly.GetTypes(); foreach (var oType in lstTypes) { if (oType.Name == "Person") { //默认获得类下面的全部public成员 var lstMembers = oType.GetMembers(); foreach (var oMem in lstMembers) { Console.WriteLine("GetMembers()方法获得的成员名称:"+oMem.Name); } Console.WriteLine(""); //默认获得类下面的全部public属性 var lstProperty = oType.GetProperties(); foreach (var oProp in lstProperty) { Console.WriteLine("GetProperties()方法获得的成员名称:" + oProp.Name); } Console.WriteLine(""); //默认获得类下面的全部public字段 var lstField = oType.GetFields(); foreach (var oField in lstField) { Console.WriteLine("GetFields()方法获得的成员名称:" + oField.Name); } } } Console.ReadKey(); }
获得结果
(2)反射对象的私有成员:
通常私有属性的用法比较少,咱们就以私有字段为例来讲明,仍是上面的例子:
static void Main(string[] args) { //反射dll var strDllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "dll\\ReflectorDLL.dll"); var oAssembly = Assembly.LoadFile(strDllPath); var lstTypes = oAssembly.GetTypes(); foreach (var oType in lstTypes) { if (oType.Name == "Person") { //默认获得类下面的全部public字段 var lstField = oType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance); foreach (var oField in lstField) { Console.WriteLine("GetFields()方法获得的成员名称:" + oField.Name); } } } Console.ReadKey(); }
(3)反射对象的静态成员:
static void Main(string[] args) { //反射dll var strDllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "dll\\ReflectorDLL.dll"); var oAssembly = Assembly.LoadFile(strDllPath); var lstTypes = oAssembly.GetTypes(); foreach (var oType in lstTypes) { if (oType.Name == "Person") { //默认获得类下面的全部public成员 var lstMembers = oType.GetMembers(BindingFlags.Public|BindingFlags.Static); foreach (var oMem in lstMembers) { Console.WriteLine("GetMembers()方法获得的成员名称:" + oMem.Name); } Console.WriteLine(""); //默认获得类下面的全部public字段 var lstField = oType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance); foreach (var oField in lstField) { Console.WriteLine("GetFields()方法获得的成员名称:" + oField.Name); } } } Console.ReadKey(); }
还有枚举类型等等就不一一介绍了,基本上都是在BindingFlags这个上面作处理。
(4)反射获得对象以及对象的操做:
反射获得对象的方法主要有两种
public static T GetModel<T>(T oModel) { var model = default(T) ; //获得对象的方法一: model = (T)typeof(T).GetConstructor(new System.Type[] { }).Invoke(new object[] { });//反射获得泛型类的实体 //获得对象的方法二: model = (T)Activator.CreateInstance(typeof(T)); //逻辑处理...... return model; }
对象属性的取值和赋值:
//List集合转换为DataTable public static DataTable ListFillTable(object obj) { if (!(obj is IList)) { return null; } var objlist = obj as IList; if (objlist == null || objlist.Count <= 0) { return null; } var tType = objlist[0]; DataTable dt = new DataTable(tType.GetType().Name); DataColumn column; DataRow row; System.Reflection.PropertyInfo[] myPropertyInfo = tType.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var t in objlist) { if (t == null) { continue; } row = dt.NewRow(); for (int i = 0, j = myPropertyInfo.Length; i < j; i++) { System.Reflection.PropertyInfo pi = myPropertyInfo[i]; string name = pi.Name; if (dt.Columns[name] == null) { var coltype = pi.PropertyType; if (coltype.Name == "Nullable`1") { //coltype = typeof(System.DBNull); column = new DataColumn(name); } else { column = new DataColumn(name, coltype); } dt.Columns.Add(column); } row[name] = pi.GetValue(t, null); } dt.Rows.Add(row); } return dt; }