C#反射
一.什么是反射?
反射 Reflection 是提供封装程序集、模块和类型的对象
程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。
二.反射的用途
1.使用 Assembly 定义和加载程序集,加载在程序集清单中列出的模块,以及从此程序集中查找类型并创建该类型的实例。
2.使用 Module 了解如下的类似信息:包含模块的程序集以及模块中的类等。您还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。
3.使用 ConstructorInfo 了解如下的类似信息:构造函数的名称、参数、访问修饰符(如 public 或 private)和实现详细信息(如 abstract 或 virtual)等。
4.使用 Type 的 GetConstructors 或 GetConstructor 方法来调用特定的构造函数。
5.使用 MethodInfo 来了解如下的类似信息:方法的名称、返回类型、参数、访问修饰符(如 public 或 private)和实现详细信 息(如 abstract 或 virtual)等。使用 Type 的
GetMethods 或 GetMethod 方法来调用特定的方法。
6.使用 FieldInfo 来了解如下的类似信息:字段的名称、访问修饰符(如 public 或 private)和实现详细信息(如 static)等;并获取或设置字段值。
7.使用 EventInfo 来了解如下的类似信息:事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等;并添加或移除事件处理程序。
8.使用 PropertyInfo 来了解如下的类似信息:属性的名称、数据类型、声明类型、反射类型和只读或可写状态等;并获取或设置属性值。
9.使用 ParameterInfo 来了解如下的类似信息:参数的名称、数据类型、参数是输入参数还是输出参数,以及参数在方法签名中的位置等。
三.实例
首先,我们创建一个普通的类库项目Alex.Reflector。如图 ![](//images0.cnblogs.com/i/129558/201403/181410434271778.png)
![](http://images0.cnblogs.com/i/129558/201403/181410434271778.png)
具体代码如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 namespace Alex.Reflector 6 { 7 public class ReflectorTest 8 { 9 10 public string Name { get; set; } 11 /// <summary> 12 /// 静态方法 13 /// </summary> 14 /// <param name="name"></param> 15 /// <returns></returns> 16 public static string StaticMethod(string name) 17 { 18 return name; 19 } 20 /// <summary> 21 /// 实例方法 22 /// </summary> 23 /// <param name="name"></param> 24 /// <returns></returns> 25 public string GetNameExample(string name) 26 { 27 return "Hi" + name; 28 } 29 /// <summary> 30 /// 无参的方法 31 /// </summary> 32 /// <returns></returns> 33 public string GetNoParameter() 34 { 35 return "没有参数"; 36 } 37 } 38 }
我们生成该类库项目会在Bin目录下生成一个Alex.Reflector.dll(根据你项目的名字,这里只是举例)的文件。
接下来。我们就要用我们的 "反射"技术来操作我们这个DLL文件。
在当前解决方案下新建一个项目名为 Alex.ReflectorDemo,如图
然后在此项目下新建一个页面,我们暂时命名为ReflectorTest.aspx 整体结构如图
ReflectorTest.aspx源码如下
1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ReflectorTest.aspx.cs" Inherits="Alex.ReflectorDemo.ReflectorTest" %> 2 3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 4 5 <html xmlns="http://www.w3.org/1999/xhtml"> 6 <head runat="server"> 7 <title>C#反射实例</title> 8 </head> 9 <body> 10 <form id="form1" runat="server"> 11 <p> 12 <asp:Button ID="btn1" runat="server" Text="利用反射去调用程序集中(包含的类)所包含的方法,属性,成员" onclick="btn1_Click" /> 13 </p> 14 <asp:Label ID="lblShowMessage" runat="server" Text=""></asp:Label> 15 <p> 16 </p> 17 <p> 18 <asp:Button ID="btn2" runat="server" Text="利用反射获取程序集中类,类的成员(方法,属性等)" 19 onclick="btn2_Click" /> 20 </p> 21 <asp:Label ID="lblShowMessage1" runat="server" Text=""></asp:Label> 22 </form> 23 </body> 24 </html>
ReflectorTest.aspx.cs源码如下。在这里我就不一一解释了。大家一看就懂。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.UI; 6 using System.Web.UI.WebControls; 7 using System.Reflection; 8 9 namespace Alex.ReflectorDemo 10 { 11 public partial class ReflectorTest : System.Web.UI.Page 12 { 13 Assembly assembly; 14 Type type; 15 MethodInfo methodinfo; 16 protected void Page_Load(object sender, EventArgs e) 17 { 18 19 } 20 /// <summary> 21 /// 利用反射去调用程序集中(包含的类)所包含的方法,属性,成员 22 /// </summary> 23 /// <param name="sender"></param> 24 /// <param name="e"></param> 25 protected void btn1_Click(object sender, EventArgs e) 26 { 27 try 28 { 29 assembly = Assembly.LoadFile(@"D:\My\Reflector\Alex.Reflector\Alex.Reflector\bin\Debug\Alex.Reflector.dll");//根据DLL的物理路径加载 30 type = assembly.GetType("Alex.Reflector.ReflectorTest");//根据类型名称反射出该类型,注意看格式是命名空间.类名 31 object strobject = Activator.CreateInstance(type);//创建该类型的对象实例 32 methodinfo = type.GetMethod("GetNameExample");//反射获取方法。实例方法 33 string s = (string)methodinfo.Invoke(strobject, new string[] { "田小贱" }); 34 lblShowMessage.Text = "调用实例方法返回:" + s.ToString()+"</br>"; 35 36 methodinfo = type.GetMethod("StaticMethod"); 37 string s1 = (string)methodinfo.Invoke(null, new string[] { "肖小仙" }); 38 lblShowMessage.Text += "调用静态方法返回:" + s1.ToString(); 39 type.GetProperty("Name").SetValue(strobject, "田小贱", null); 40 } 41 catch (Exception) 42 { 43 throw; 44 } 45 finally 46 { 47 assembly = null; 48 type = null; 49 methodinfo = null; 50 51 } 52 } 53 /// <summary> 54 /// 利用反射获取程序集中类,类的成员(方法,属性等) 55 /// </summary> 56 /// <param name="sender"></param> 57 /// <param name="e"></param> 58 protected void btn2_Click(object sender, EventArgs e) 59 { 60 assembly = Assembly.LoadFile(@"D:\My\Reflector\Alex.Reflector\Alex.Reflector\bin\Debug\Alex.Reflector.dll");//根据DLL的物理路径加载 61 Module[] module = assembly.GetModules();//获取作为程序集的一部分的所有模块 62 Type[] types = assembly.GetTypes(); //获取程序集中定义的所有类型 63 64 foreach (var item in types) 65 { 66 lblShowMessage1.Text ="所包含的类型名称:"+ item.Name+"</br>"; 67 MethodInfo[] methodinfos=item.GetMethods();// (MethodInfo)发现方法的属性,并提供对方法元数据的访问)获取该类型下所包含的方法信息 68 foreach (var method in methodinfos) 69 { 70 lblShowMessage1.Text += "该类所包含的方法名称:"+method.Name+"</br>"; 71 } 72 PropertyInfo[] propertyInfo = item.GetProperties();//(ProperInfo)发现属性的特性,并提供对该属性元数据的访问 73 74 foreach (var property in propertyInfo) 75 { 76 lblShowMessage1.Text += "该类所包含的属性名称:" + property.Name; ; 77 } 78 } 79 80 } 81 } 82 }
多话不说,直接看运行效果。
最后。提醒大家一下。反射相对来说会影响性能。 希望大家根据自己实际情况去合理使用。