首页 > 代码库 > C#反射机制学习总结 .

C#反射机制学习总结 .

反射的定义:审查元数据并收集关于它的类型信息的能力。元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等。

System.reflection命名空间包含的几个类,允许你反射(解析)这些元数据表的代码,如下所示:

[csharp] view plaincopyprint?
  1. System.Reflection.Assembly   
  2. System.Reflection.MemberInfo  
  3. System.Reflection.EventInfo  
  4. System.Reflection.FieldInfo  
  5. System.Reflection.MethodBase  
  6. System.Reflection.ConstructorInfo  
  7. System.Reflection.MethodInfo  
  8. System.Reflection.PropertyInfo  
  9. System.Type  
System.Reflection.Assembly System.Reflection.MemberInfoSystem.Reflection.EventInfoSystem.Reflection.FieldInfoSystem.Reflection.MethodBaseSystem.Reflection.ConstructorInfoSystem.Reflection.MethodInfoSystem.Reflection.PropertyInfoSystem.Type

以下是上面几个类的使用方法:
(1)使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。 
(2)使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。 
(3)使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetConstructors或 GetConstructor方法来调用特定的构造函数。 
(4)使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetMethods或GetMethod方法来调用特定的方法。 
(5)使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。 
(6)使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。 
(7)使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。 

(8)使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。

     

 反射的层次模型:

                      

 

 

 

void Main  

  • {  
  •        //通过GetAssemblies 调用appDomain的所有程序集   
  •        foreach (Assembly assem in Appdomain.currentDomain.GetAssemblies())  
  •       {  
  •        //反射当前程序集的信息   
  •             reflector.ReflectOnAssembly(assem)  
  •       }  
  • }  
 
static void Main{       //通过GetAssemblies 调用appDomain的所有程序集       foreach (Assembly assem in Appdomain.currentDomain.GetAssemblies())      {       //反射当前程序集的信息            reflector.ReflectOnAssembly(assem)      }}


说明:调用AppDomain 对象的GetAssemblies 方法 将返回一个由System.Reflection.Assembly元素组成的数组。

 

 

 

[csharp] view plaincopyprint?
  1. using system;  
  2. using sytem.reflection;  
  3. class reflecting   
  4. {  
  5.        static void Main(string[]args)  
  6.        {  
  7.              reflecting reflect=new reflecting();//定义一个新的自身类   
  8.              //调用一个reflecting.exe程序集   
  9.   
  10.              assembly myAssembly =assembly.loadfrom(“reflecting.exe”)  
  11.              reflect.getreflectioninfo(myAssembly);//获取反射信息   
  12.        }  
  13.   
  14.        //定义一个获取反射内容的方法   
  15.        void getreflectioninfo(assembly myassembly)  
  16.        {  
  17.              type[] typearr=myassemby.Gettypes();//获取类型   
  18.              foreach (type type in typearr)//针对每个类型获取详细信息   
  19.             {  
  20.                    //获取类型的结构信息   
  21.                   constructorinfo[] myconstructors=type.GetConstructors;  
  22.   
  23.                  //获取类型的字段信息   
  24.                  fieldinfo[] myfields=type.GetFiedls()  
  25.   
  26.                  //获取方法信息   
  27.                  MethodInfo   myMethodInfo=type.GetMethods();  
  28.   
  29.                  //获取属性信息   
  30.                  propertyInfo[] myproperties=type.GetProperties  
  31.   
  32.                  //获取事件信息   
  33.                  EventInfo[] Myevents=type.GetEvents;  
  34.            }  
  35.       }  
  36. }  
using system;using sytem.reflection;class reflecting {       static void Main(string[]args)       {             reflecting reflect=new reflecting();//定义一个新的自身类             //调用一个reflecting.exe程序集             assembly myAssembly =assembly.loadfrom(“reflecting.exe”)             reflect.getreflectioninfo(myAssembly);//获取反射信息       }       //定义一个获取反射内容的方法       void getreflectioninfo(assembly myassembly)       {             type[] typearr=myassemby.Gettypes();//获取类型             foreach (type type in typearr)//针对每个类型获取详细信息            {                   //获取类型的结构信息                  constructorinfo[] myconstructors=type.GetConstructors;                 //获取类型的字段信息                 fieldinfo[] myfields=type.GetFiedls()                 //获取方法信息                 MethodInfo   myMethodInfo=type.GetMethods();                 //获取属性信息                 propertyInfo[] myproperties=type.GetProperties                 //获取事件信息                 EventInfo[] Myevents=type.GetEvents;           }      }}


其它几种获取type对象的方法:
1、System.type   参数为字符串类型,该字符串必须指定类型的完整名称(包括其命名空间)
2、System.type 提供了两个实例方法:GetNestedType,GetNestedTypes
3、Syetem.Reflection.Assembly 类型提供的实例方法是:GetType,GetTypes,GetExporedTypes
4、System.Reflection.Moudle 提供了这些实例方法:GetType,GetTypes,FindTypes

 

 

设置反射类型的成员:
反射类型的成员就是反射层次模型中最下面的一层数据。我们可以通过type对象的GetMembers 方法取得一个类型的成员。如果我们使用的是不带参数的GetMembers,它只返回该类型的公共定义的静态变量和实例成员,我们也可以通过使用带参数的 GetMembers通过参数设置来返回指定的类型成员。具体参数参考msdn 中system.reflection.bindingflags 枚举类型的详细说明。

例如:

 

[csharp] view plaincopyprint?
  1. //设置需要返回的类型的成员内容   
  2. bindingFlags bf=bingdingFlags.DeclaredOnly|bingdingFlags.Nonpublic|BingdingFlags.Public;  
  3. foreach (MemberInfo mi int t.getmembers(bf))  
  4. {  
  5.        writeline(mi.membertype)    //输出指定的类型成员   
  6. }  
//设置需要返回的类型的成员内容bindingFlags bf=bingdingFlags.DeclaredOnly|bingdingFlags.Nonpublic|BingdingFlags.Public;foreach (MemberInfo mi int t.getmembers(bf)){       writeline(mi.membertype)    //输出指定的类型成员}

 

 

 

[csharp] view plaincopyprint?
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.Text.RegularExpressions;  
  5. using System.Web.UI;  
  6. using System.Collections;  
  7. namespace cn.SwordYang  
  8. {  
  9.     public class TextClass:System.Web.UI.Page  
  10.     {  
  11. public static void RunJs(Page _page, string Source)  
  12.         {  
  13.             _page.ClientScript.RegisterStartupScript(_page.GetType(), "", "<script type=\"text/javascript\">" + Source + ";</script>");  
  14.         }  
  15. }  
  16. }  
  17. //调用代码   
  18. System.Reflection.Assembly ass = Assembly.LoadFrom(Server.MapPath("bin/swordyang.dll")); //加载DLL   
  19.             System.Type t = ass.GetType("cn.SwordYang.TextClass");//获得类型   
  20.             object o = System.Activator.CreateInstance(t);//创建实例   
  21.             System.Reflection.MethodInfo mi = t.GetMethod("RunJs");//获得方法   
  22.             mi.Invoke(o, new object[] { this.Page,"alert(‘测试反射机制‘)"});//调用方法  
using System;using System.Collections.Generic;using System.Text;using System.Text.RegularExpressions;using System.Web.UI;using System.Collections;namespace cn.SwordYang{    public class TextClass:System.Web.UI.Page    {public static void RunJs(Page _page, string Source)        {            _page.ClientScript.RegisterStartupScript(_page.GetType(), "", "<script type=\"text/javascript\">" + Source + ";</script>");        }}}//调用代码System.Reflection.Assembly ass = Assembly.LoadFrom(Server.MapPath("bin/swordyang.dll")); //加载DLL            System.Type t = ass.GetType("cn.SwordYang.TextClass");//获得类型            object o = System.Activator.CreateInstance(t);//创建实例            System.Reflection.MethodInfo mi = t.GetMethod("RunJs");//获得方法            mi.Invoke(o, new object[] { this.Page,"alert(‘测试反射机制‘)"});//调用方法


反射机制对应设计模式中的策略模式。