程序集和反射(二)

上篇文章主要介绍了程序集的内容:程序集和反射(一),时隔这么久,今天终于腾出点时间,把反射部分的知识点给整理一下,不把这个写完,心里总觉得有点堵。对于反射,我相信很多人跟LZ一个德行,不会,所以不用,不用,所以永远不会。

     通过System.Reflection命名空间中的类已经System.Type,您可以获取有关已加载的程序集和在其中定义的类型(如类、接口、值类型)的信息。您也可以使用反射在运行时创建类型实例,以及调用和访问这些实例。

     程序集包含模块,而模块包含类型,类型又包含成员。 反射则提供了封装程序集、模块和类型的对象。 您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。 然后,可以调用类型的方法或访问其字段和属性。

    反射通常具有以下用途:

  • 类型 作用
    Assembly 定义和加载程序集,加载在程序集清单中列出的模块,以及从此程序集中查找类型并创建该类型的实例。用来获取程序集内部信息
    EventInfo 发现以下信息:事件的名称、事件处理程序数据类型、自定义特性、声明类型和反射类型等;并添加或移除事件处理程序。
    FieldInfo  发现以下信息:字段的名称、访问修饰符(如 public 或 private)和实现详细信息(如 static)等;并获取或设置字段值 。该类保存给定的字段信息
    MethodInfo 发现以下信息:方法的名称、返回类型、参数、访问修饰符(如 public 或 private)和实现详细信息(如 abstract 或 virtual)等。 使用 Type 的 GetMethods 或 GetMethod 方法来调用特定的方法。该类保存给定的方法信息
    MemberInfo 该类是一个基类,它定义了EventInfo、FieldInfo、MethodInfo、PropertyInfo的多个公用行为
    Module 发现以下信息:包含模块的程序集以及模块中的类等。 您还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。该类可以使你能访问多个程序集中的给定模块
    ParameterInfo 发现以下信息:参数的名称、数据类型、参数是输入参数还是输出参数,以及参数在方法签名中的位置等。该类保存给定的参数信息      
    PropertyInfo 发现以下信息:属性的名称、数据类型、声明类型、反射类型和只读或可写状态等;并获取或设置属性值。该类保存给定的属性信息
  • 使用 ConstructorInfo 发现以下信息:构造函数的名称、参数、访问修饰符(如 public 或 private)和实现详细信息(如 abstract 或 virtual)等。 使用 Type 的 GetConstructors 或 GetConstructor 方法来调用特定的构造函数。(以上内容参考MSDN)

 Type类

          表示类型声明:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。

           可以通过以下两种方式获得Type:

                 1.通过类获得Type:   Type t=typeof(Person);

                 2.通过对象获得Type:Person p=new Person();  Type t=p.GetType();

           这里仍然采用上篇文章中的示例:

 1       static void Main(string[] args)
 2         {
 3             //通过反射动态调用另一个程序集中的方法
 4             //1加载程序集
 5             string path = AppDomain.CurrentDomain.BaseDirectory;//获取当前.exe执行文件的路径
 6             path = Path.Combine(path, "MyAssembly.dll");//拼接程序集的路径
 7             Assembly assembly = Assembly.LoadFile(path);
 8             //2创建Person类的对象
 9             Type type = assembly.GetType("MyAssembly.Person");
10             object o = Activator.CreateInstance(type,"wolf",22,"未知");//实例化
11             //3获取方法的类型
12              MethodInfo methodInfo = type.GetMethod("SayHi");
13             //4反射调用方法
14              methodInfo.Invoke(o, null);
15             Console.Read();
16         }

    调用Assembly的GetExportedTypes方法可以得到Assembly中定义的所有的public类型。

    调用Assembly的GetTypes()方法可以得到Assembly中定义的所有的类型。

    调用Assembly的GetType(name)方法可以得到Assembly中定义的全名为name的类型信息。如: Type type = assembly.GetType("MyAssembly.Person");

动态创建对像

     Activator.CreateInstance(Type t)会动态调用类的无参构造函数创建一个对象,返回值就是创建的对象,如果类没有无参构造函数就会报错。

     GetConstructor(参数列表);//这个是找到带参数的构造函数。例如:object o = Activator.CreateInstance(type,"wolf",22,"未知");//实例化

Type类的方法

     bool IsAssignableFrom(Type c):判断当前的类型的变量是不是可以接受c类型变量的赋值。

1             Type type = assembly.GetType("MyAssembly.Person");
2             Type studentType = assembly.GetType("MyAssembly.Student");
3             Console.WriteLine(type.IsAssignableFrom(studentType));

      Result:True      因为Person p=new Student();

     typeof(IPlugin).IsAssignableFrom(t)   

     bool IsInstanceOfType(object o):判断对象o是否是当前类的实例(当前类可以是o的类、父类、接口)  

                Person p = new Student();

                //判断p是否是一个Student类的实例

                 bool r = typeof(Student).IsInstanceOfType(p);//True

 

     bool IsSubclassOf(Type c):判断当前类是否是类c的子类。实用于类,不适用于接口

//判断Student是否是Person的子类
bool r = typeof(Student).IsSubclassOf(typeof(Person));//Tru

     IsAbstract,判断是否为抽象的,含接口

 //判断Person是否是抽象类或接口
 bool r = typeof(Person).IsAbstract;//False

 动态调用成员

    MemberInfo类  抽象类,有很多子类,下面讲的类都继承自它,获取程序集成员的相关信息(类型、方法、事件、字段和属性)

    PropertyInfo  获取属性

    主要成员:CanRead、CanWrite、PropertyType属性类型;SetValue、GetValue:读取值,设置值,第一个参数是实例对象,因为set、get要针对具体实例,最后一个参数null。pInfo.SetValue(p1, 30, null)

    MethodInfo  获取方法

    MethodInfo   都是和具体对象不相关的,所以需要第一个参数指定要执行的对象。

//3获取方法的类型
MethodInfo methodInfo = type.GetMethod("SayHi");

    FieldInfo     获取字段

    EventInfo     获取事件

案例:

<?xml version="1.0" encoding="utf-8" ?>
<Persons>
  <person>
    <Name>wolfy1</Name>
    <Age>22</Age>
    <Gender>男</Gender>
  </person>
  <person>
    <Name>wolfy2</Name>
    <Age>23</Age>
    <Gender>女</Gender>
  </person>
  <person>
    <Name>wolfy3</Name>
    <Age>24</Age>
    <Gender>未知</Gender>
  </person>
</Persons>

 

     控制台程序测试程序:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.IO;
 6 using System.Reflection;
 7 using System.Xml;
 8 using System.Xml.Linq;
 9 namespace AssemblyDemo
10 {
11     class Program
12     {
13
14         static void Main(string[] args)
15         {
16             //通过反射动态调用另一个程序集中的方法
17             //1加载程序集
18             string path = AppDomain.CurrentDomain.BaseDirectory;//获取当前.exe执行文件的路径
19             string xmlPath = Path.Combine(path, "Person.xml");
20             path = Path.Combine(path, "MyAssembly.dll");//拼接程序集的路径
21             XElement xml;
22             Assembly assembly = Assembly.LoadFile(path);
23             xml = XElement.Load(xmlPath);
24             //2创建Person类的对象
25             Type type = assembly.GetType("MyAssembly.Person");
26             foreach (var item in xml.Elements("person"))
27             {
28                 PropertyInfo[] properties = type.GetProperties();
29                 foreach (PropertyInfo p in properties)
30                 {
31                     Console.Write(item.Element(p.Name).Value+"\t");
32                 }
33                 Console.WriteLine();
34             }
35             Console.Read();
36         }
37     }
38 }

      结果:

       

 

 结语:

       关于程序集和反射的基础,就介绍到这里,怎么样去掌握,还得勤思考,多用才行。 

博客地址: http://www.cnblogs.com/wolf-sun/
博客版权: 本文以学习、研究和分享为主,欢迎转载,但必须在文章页面明显位置给出原文连接。
如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步!
再次感谢您耐心的读完本篇文章。

转载:http://www.cnblogs.com/wolf-sun/p/3364009.html

时间: 2024-10-03 14:07:37

程序集和反射(二)的相关文章

程序集和反射(一)

什么是程序集? 1.程序集(assembly)是一个及一个以上托管模块,以及一些资源文件的逻辑组合. 2.程序集是组件复用,以及实施安全策略和版本策略的最小单位. 3.程序集是包含一个或者多个类型定义文件和资源文件的集合.在程序集包含的所有文件中,有一个文件用于保存清单.(清单是元数据部分中一组数据表的集合,其中包含了程序集中一部分文件的名称,描述了程序集的版本,语言文化,发布者,共有导出类型,以及组成该程序集的所有文件). 4.在编译应用程序中,所创建的CIL代码存储在一个程序集中,程序集包括

有同事看到有人用vs2010编程制作的VB程序可以带二次编译功能?

问题描述 如题有同事看到有人用vs2010编程制作的VB程序可以带二次编译功能?有大神知道这是怎么实现的?是嵌入什么编译器? 解决方案 解决方案二:.netframework本身就提供命令行的编译器啊?!关键是靠不靠谱,而不是有没有.每一个人都能买到手术刀,但是买到手术刀的人未必就能随便给别人做外科手术.解决方案三:你搜索一下vbc.exe就行了.你可以让用户录入一段vb.net源代码,然后给他编译为dll.问题是,假设你需要动态链接一个dll,你一定要给他提供一个源代码编辑器吗?你让他自己按照

哪位大虾帮我看看这个网站用的什么程序做的二次开发?

问题描述 刚看到一个技术站,做的不错,看上去像是用哪个Asp.net论坛程序做的二次开发.但是看起来不像Discuz!nt,但的确是Asp.net开发的.哪位大虾知道,告诉小弟一下,偶也想弄一个研究研究哈.地址: 解决方案 解决方案二:bbsmax.com解决方案三:楼上说的对,bbsmax,一个不错的程序.你给的技术站,也不错,顶一下解决方案四:该回复于2011-11-28 14:26:09被版主删除解决方案五:求源码解决方案六:看着用的人好像不多呀.也可能这个不是主力网站.解决方案七:好像这

微信小程序把玩(二)window配置

原文:微信小程序把玩(二)window配置 window用于设置小程序的状态栏.导航条.标题.窗口背景色.注意在app.json中配置的属性会被子window属性覆盖 只需在app.json配置即可

微信小程序把玩(二十二)action-sheet组件

原文:微信小程序把玩(二十二)action-sheet组件 action-sheet组件是从底部弹出可选菜单项,估计也是借鉴IOS的设计添加的,action-sheet有两个子组件, action-sheet-item为每个选项,action-sheet-cancel取消选项,与action-sheet-item中间会有间隔,并且点击会触发action-sheet监听事件 主要属性: wxml <!--触发action-sheet事件--> <button type="prim

微信小程序把玩(二十)slider组件

原文:微信小程序把玩(二十)slider组件 slider滑动组件用的不太多,在其他平台反正我是用的不多 主要属性: wxml <slider max="100" step="10" show-value="true" bindchange="listenerSlider" /> js Page({ data:{ // text:"这是一个页面" }, /** * 监听slider */ lis

微信小程序把玩(二十四)toast组件

原文:微信小程序把玩(二十四)toast组件 toast消息提示框,可用在提示一些信息,比如清楚缓存给用户一个友好的提示!或操作一些请求不想让用户有什么操作,toast也可以做到因为toast显示时其他操作是无效的 主要属性: wxml <!--点击button触发toast--> <button type="primary" bindtap="listenerButton">点击显示toast</button> <!--t

微信小程序把玩(二十九)video组件

原文:微信小程序把玩(二十九)video组件 视频播放组件与图片加载组件也没啥差别,使用起来也没啥注意的 重要属性: wxml <!--监听button点击事件--> <button bindtap="listenerButton">点击显示视频组件</button> <!--视频组件src资源地址,binderror为监听错误信息--> <video src="http://mvvideo1.meitudata.com/

微信小程序把玩(二十五)loading组件

原文:微信小程序把玩(二十五)loading组件 loading通常使用在请求网络数据时的一种方式,通过hidden属性设置显示与否 主要属性: wxml <!----> <button type="primary" bindtap="listenerButton">显示loading</button> <!--默认隐藏--> <loading hidden="{{hiddenLoading}}&quo