C#基础系列:反射笔记

时间:2021-12-28 08:39:46

1、为什么需要反射:

最初使用反射的时候,作为小菜总是不理解,既然可以通过new 一个对象的方式得到对象,然后通过对象去调用属性和方法,那么为什么还需要反射去调用呢?后来使用多了发现这就是一个先绑定还是后绑定的问题,很多初使用反射的开发人员通常都会有类似这种疑虑:既然在开发时就能够写好代码,干嘛还放到运行期去做,,不光繁琐,而且效率也受影响。博主觉得主要是适用性的问题,如果你的系统没有那么高的扩展性和灵活性要求,你大可不必考虑反射。但在架构设计时,很多东西都需要考虑复用性,并且在某些特定的场景下你得不到具体的类时,你就必须用到反射。博主总结了下自己使用过的反射场景:

(1)有时不知道具体的类型,可以通过dll去得到类的对象;

(2)某些特殊方法,传过来的是泛型类,需要通过反射处理某些特殊的业务;

(3)通用方法DataTable和List<T>的相互转化时需要用到反射;

2、如何使用反射:

(1)反射dll得到类成员:

在一个未知的dll里面有一个Person类

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类

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(); }

得到结果

C#基础系列:反射笔记

(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(); }

C#基础系列:反射笔记

(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(); }

C#基础系列:反射笔记

还有枚举类型等等就不一一介绍了,基本上都是在BindingFlags这个上面做处理。

(4)反射得到对象以及对象的操作: