反射的定义:审查元数据并收集关于它的类型信息的能力。元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等。
System.reflection命名空间包含的几个类,允许你反射(解析)这些元数据表的代码,如下所示:
- System.Reflection.Assembly
- System.Reflection.MemberInfo
- System.Reflection.EventInfo
- System.Reflection.FieldInfo
- System.Reflection.MethodBase
- System.Reflection.ConstructorInfo
- System.Reflection.MethodInfo
- System.Reflection.PropertyInfo
- System.Type
System.Reflection.Assembly System.Reflection.MemberInfo System.Reflection.EventInfo System.Reflection.FieldInfo System.Reflection.MethodBase System.Reflection.ConstructorInfo System.Reflection.MethodInfo System.Reflection.PropertyInfo System.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元素组成的数组。
- 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;
- }
- }
- }
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 枚举类型的详细说明。
例如:
- //设置需要返回的类型的成员内容
- bindingFlags bf=bingdingFlags.DeclaredOnly|bingdingFlags.Nonpublic|BingdingFlags.Public;
- foreach (MemberInfo mi int t.getmembers(bf))
- {
- writeline(mi.membertype) //输出指定的类型成员
- }
//设置需要返回的类型的成员内容 bindingFlags bf=bingdingFlags.DeclaredOnly|bingdingFlags.Nonpublic|BingdingFlags.Public; foreach (MemberInfo mi int t.getmembers(bf)) { writeline(mi.membertype) //输出指定的类型成员 }
- 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('测试反射机制')"});//调用方法
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('测试反射机制')"});//调用方法
反射机制对应设计模式中的策略模式。