关键词Assembly
使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。
Module
通过它可以获取包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。
MemberInfo
这是一个基类,它定义了EventInfo、FieldInfo、MethodInfo、PRopertyInfo的多个公用行为。
Type
是System命名空间下的一个类,一般用于装载反射得到的类对象,通过Type可以得到一个类的内部信息,也可以通过它反射创建一个对象。
EventInfo
通过它可以获取事件的相关信息。如事件的名称、事件处理程序数据类型、声明类型等,还可以添加或移除事件处理程序。
FieldInfo
可以通过它获取字段的相关信息。如字段的名称、访问修饰符等,还可以获取或设置字段值。
MethodInfo
通过它可以获取方法的相关信息。例如方法的名称、返回类型、参数、访问修饰符等。使用Type的GetMethods或GetMethod方法来调用特定的方法。
PropertyInfo
通过它可以获取属性的相关信息。例如属性的名称、数据类型、声明类型和只读或可写状态等,还可以获取或设置属性值。
ConstructorInfo
通过它可以了解构造函数的属性及调用构造函数。可以由Type对象的GetConstructors或GetConstructor方法返回的。
ParameterInfo
通过它可以了解参数相关信息。例如参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。
什么是反射?Reflection,中文翻译为反射,是.Net中获取运行时类型信息的方式。
.Net的应用程序由几个部分:程序集(Assembly)、模块(Module)、类型 (class)组成,而反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组成部分的相关信息。
如何使用反射获取程序集?通过Assembly类对象的Load方法、LoadFrom方法和LoadFile方法可以获取程序集的相关信息。
三者之间的区别:
LoadFrom和Load差不多,只是LoadFrom是多了先获取其中的程序集版本,语言文化,公钥标记等信息,把他们传递给 Load方法这一步。
LoadFrom不能用于加载标识相同但路径不同的程序集。
LoadFile 方法用来来加载和检查具有相同标识但位于不同路径中的程序集.但不会加载程序的依赖项。
1、Assembly.LoadFile只载入相应的dll文件,比如Assembly.LoadFile("abc.dll"),则载入abc.dll,假如abc.dll中引用了def.dll的话,def.dll并不会被载入。
Assembly.LoadFrom则不一样,它会载入dll文件及其引用的其他dll,比如上面的例子,def.dll也会被载入。
2、用Assembly.LoadFrom载入一个Assembly时,会先检查前面是否已经载入过相同名字的Assembly,比如abc.dll有两个版本(版本1在目录1下,版本2放在目录2下),程序一开始时载入了版本1,当使用Assembly.LoadFrom("2//abc.dll")载入版本2时,不能载入,而是返回版本1。
Assembly.LoadFile的话则不会做这样的检查,比如上面的例子换成Assembly.LoadFile的话,则能正确载入版本2。
如何使用反射获取模块?1、用Object.GetType().Module来获取。
2、用Assembly类对象的GetModules方法来获取。
如何使用反射获取Type对象?1、用typeof运算符获取。
2、用静态方法Type.GetType来获取。
3、用Assembly类对象的GetType或者GetTypes方法来获取。
如何根据类型来动态创建对象?1、用System.Reflection空间下的Assembly类对象的CreateInstance方法来创建对象。
2、用System.Activator类提供的静态方法CreateInstance来创建对象。
如何获取方法以及动态调用特定的方法?通过Type类对象的GetMethod或者GetMethods方法获取到类里面的方法,然后用MethodInfo对象的Invoke方法去执行。
如何获取字段以及动态设置获取它?通过Type类对象的GetField方法来获取字段,用FieldInfo对象存储获取到的字段,可以通过FieldInfo对象的GetValue和SetValue方法读取和设置字段。
如何获取属性以及动态设置获取它?通过Type类对象的GetPropertie或者GetProperties方法来获取属性,用PropertyInfo对象存储获取到的属性,然后通过PropertyInfo对象的GetValue和SetValue方法读取和设置属性值。
动手尝试1、创建个类库工程,在这工程里面定义一个类。(我这里工程名为:Study__Reflection,类名为:StudyReflection)
1namespaceStudy__Reflection2{3publicclassStudyReflection4{5///<summary>6///学习7///</summary>8///<param name="name">姓名</param>9///<returns>字符串</returns>10publicstringStudy(stringname)11{12returnname +"正在学习反射";13}14///<summary>15///无参构造函数16///</summary>17publicStudyReflection() { }1819///<summary>20///有参构造函数21///</summary>22///<param name="a"></param>23///<param name="b"></param>24publicStudyReflection(inta,intb)25{26SetValue(a, b);27}2829#region私有成员变量30privateintx;31privateinty;32publicstringStatus;33#endregion3435#region属性36publicintX37{38get{returnx; }39set{ x =value; }40}4142publicintY43{44get{returny; }45set{ y =value; }46}4748#endregion49///<summary>50///计算x和y的和51///</summary>52///<returns>x+y</returns>53publicintsum()54{55returnx +y;56}5758///<summary>59///取2个数之间的商的整数60///</summary>61///<param name="z"></param>62///<param name="t"></param>63///<returns></returns>64publicintdiv(intz,intt)65{66returnz/t;67}6869///<summary>70///计算x和y的积71///</summary>72///<returns>x*y</returns>73privateintproduct()74{75returnx *y;76}77///<summary>78///给x和y赋值79///</summary>80///<param name="a">整形a</param>81///<param name="b">整形b</param>82publicvoidSetValue(inta,intb)83{84x =a;85y =b;86}87}88}
View Code
把这工程指定好路径编译好。生成的dll文件就是准备用于学习反射相关知识的。
下面是反射的基本用法:
1//获取程序集2Assembly asem = Assembly.LoadFrom("../lib/Study_ Reflection.dll");3//Assembly asem2 = Assembly.Load("Study_ Reflection, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");4//Assembly asem3 = Assembly.LoadFile(@"D:\mythings\Study\lib\Study_ Reflection.dll");//注意是全路径56//用Object.GetType().Module来获取。7Class1 cc =newClass1();8Module m =cc.GetType().Module;9//用Assembly类对象的GetModules方法来获取。10if(asem ==null)11{12asem = Assembly.LoadFrom("../lib/Study_ Reflection.dll");13}14Module[] ms =asem.GetModules();1516//通过Assembly.GetType获取Type17Type t = asem.GetType("Study__Reflection.StudyReflection");1819//通过Assembly.CreateInstance进行无参数实例化20objectawc = asem.CreateInstance("Study__Reflection.StudyReflection",true);21//通过Activator.CreateInstance进行无参数实例化22objectaa = Activator.CreateInstance(asem.FullName,"Study__Reflection.StudyReflection").Unwrap();23//通过Activator.CreateInstance方法传入Type对象执行默认的无参数构造函数来创建实例24objecto =Activator.CreateInstance(t);25//通过Assembly.CreateInstance进行有参数实例化26object[] te =newobject[2] {100,200};27objectayc = asem.CreateInstance("Study__Reflection.StudyReflection",true, BindingFlags.Default,null, te,null,null);2829//属性30PropertyInfo[] ps = t.GetProperties();//通过Type.GetProperties获取属性31PropertyInfo p = t.GetProperty("X");//通过Type.GetPropertie来获取指定名称的属性32p.SetValue(o,99);//给X属性赋值33p.GetValue(o);//读取X属性34//获取字段35FieldInfo[] fs = t.GetFields();//通过Type.GetFields获取字段36FieldInfo f = t.GetField("Status");//通过Type.GetField来获取指定名称的字段37f.SetValue(o,"奋发图强");//给Status字段赋值38f.GetValue(o);//读取Status字段39//获取方法40MethodInfo[] methods = t.GetMethods();//通过Type.GetMethods获取方法41MethodInfo method_div = t.GetMethod("div");//通过Type.GetMethod来获取指定名称的方法42method_div.Invoke(o,newobject[] {2222,333});//调用有2个参数的div方法
View Code