谈谈:程序集加载和反射
来源:互联网 发布:网络盒子电视直播软件 编辑:程序博客网 时间:2024/05/21 07:30
最近一直都在看关于程序集加载和反射方面的资料, 所以在这里把我所学习到的东西记录下来,方便自己以后复习,也给园子里面不懂的朋友参考。
一、程序集的加载
JIT编译器器将IL代码编译成本地代码时, 会查看IL代码中引用了哪些类型。在运行过程中,JIT编译器利用程序集的TypeRef和AssemblyRef元数据表来确定哪一个程序集定义了所引用的类型,然后JIT编译器将对应程序集加载到AppDomain中,在内部,CLR使用System.Reflection.Assembly类的静态方法Load来尝试加载一个程序集。然而如果我们想动态加载一个程序集时,可以使用Assembly的Load方法来动态加载程序集,其中Assembly类中还提供了其他的加载程序集方法,有LoadFrom(string path), LoadFile(stringassemblyFile)等,具体方法的使用和解释可以参照MSDN中的介绍:http://msdn.microsoft.com/zh-cn/library/xbe1wdx9
二、反射机制
.net中反射在运行中过程中解析程序集中的元数据,获得类型中的成员(包括字段、构造器、方法、属性、事件等)信息。
动态加载一个程序集并获得类型中的成员
把下面的类放在一个类库工程中,并编译生成程序集(例如为ClassLibrary1.dll,假设把dll放在D盘根目录下面)
public class ReflectTestClass { public string name; public int age; public string Name { get { return name; } set { name = value; } } public int Age { get { return age; } set { age = value; } } /// <summary> /// No Paramter Constructor /// </summary> public ReflectTestClass() { } /// <summary> /// Constructor with Parameter /// </summary> /// <param name="name"></param> /// <param name="age"></param> public ReflectTestClass(string names,int ages) { this.name = names; this.age = ages; } public string writeString(string name) { return "Welcome " + name; } public static string WriteName(string name) { return "Welcome "+name +" Come here"; } public string WirteNopara() { return "The method is no parameter "; } }然后建立一个控制台程序用来动态加载上面生成的程序集和输出类型中的成员,代码中有详细的介绍。
class Program { static void Main(string[] args) { Assembly ass; Type[] types; Type typeA; object obj; try { // 从本地中 加载程序集 然后从程序集中通过反射获得类型的信息的,并且调用方法 ass = Assembly.LoadFrom(@"D:\ClassLibrary1.dll"); types = ass.GetTypes(); foreach (Type type in types) { Console.WriteLine("Class Name is " + type.FullName); Console.WriteLine("Constructor Information"); Console.WriteLine("-----------------------"); // 获取类型的结构信息 ConstructorInfo[] myconstructors = type.GetConstructors(); ShowMessage<ConstructorInfo>(myconstructors); Console.WriteLine("Fields Information"); Console.WriteLine("-----------------------"); // 获取类型的字段信息 FieldInfo[] myfields = type.GetFields(); ShowMessage<FieldInfo>(myfields); Console.WriteLine("All Methods Information"); Console.WriteLine("-----------------------"); // 获取方法信息 MethodInfo[] myMethodInfo = type.GetMethods(); ShowMessage<MethodInfo>(myMethodInfo); Console.WriteLine("All Properties Information"); Console.WriteLine("-----------------------"); // 获取属性信息 PropertyInfo[] myproperties = type.GetProperties(); ShowMessage<PropertyInfo>(myproperties); } // 用命名空间+类名获取类型 typeA = ass.GetType("ClassLibrary1.ReflectTestClass"); // 获得方法名称 MethodInfo method = typeA.GetMethod("writeString"); // 创建实例 obj = ass.CreateInstance("ClassLibrary1.ReflectTestClass"); string result = (String)method.Invoke(obj,new string[] {"Tom"}); Console.WriteLine("Invoke Method With Parameter"); Console.WriteLine("-----------------------"); Console.WriteLine(result); Console.WriteLine("-----------------------"); Console.WriteLine(); method = typeA.GetMethod("WriteName"); result = (string)method.Invoke(null,new string[] {"Tom"}); Console.WriteLine("Invoke Static Method with Parameter"); Console.WriteLine("-----------------------"); Console.WriteLine(result); Console.WriteLine("-----------------------"); Console.WriteLine(); method = typeA.GetMethod("WirteNopara"); Console.WriteLine("Invoke Method with NOParameter"); result = (string)method.Invoke(obj, null); Console.WriteLine("-----------------------"); Console.WriteLine(result); Console.WriteLine("-----------------------"); } catch(FileNotFoundException ex) { Console.WriteLine(ex.Message); } Console.ReadLine(); } /// <summary> /// 显示数组信息 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="os"></param> public static void ShowMessage<T>(T[] array) { foreach(T member in array) { Console.WriteLine(member.ToString()); } Console.WriteLine("-----------------------"); Console.WriteLine(); } }
筛选返回的成员种类
可以调用Type的GetMembers,GetFields,GetMethods,GetProperties或者GetEvenents方法来查询一个类型的成员。在调用上面的任何一个方法时,都可以传递System.Reflection.BindingFlags枚举类型的一个实例,使用这个枚举类型目的是对这些方法返回的成员进行筛选。对于这个枚举类型中成员的信息可以参考MSDN:http://msdn.microsoft.com/zh-cn/library/system.reflection.bindingflags(v=VS.80).aspx
注意:在返回一个成员集合的所有方法中, 都有一个不获取任何实参的重载版本。如果不传递BindingFlags实参,所有这些方法都返回公共成员,默认设置为BindingFlags.Public|BindingFlags.Instance|BindingFlags.Static. (如果指定Public或NonPublic,那么必须同时指定Instance,否则不返回成员)。
- 谈谈:程序集加载和反射
- 程序集加载和反射
- 应用程序配置和动态加载5----反射程序集
- 反射动态加载程序集Assembly.Load和Assembley.LoadFrom
- 程序集和反射
- 程序集和反射
- 反射和程序集
- 加载程序集,实现编辑器插件(反射)
- 《CLR via C#》第22章 程序集加载和反射 读书笔记
- 《CLR via C#:框架设计》读书笔记 - 程序集加载和反射
- C# 程序集 和 反射
- C#程序集和反射
- 类加载和反射
- 谈谈反射
- c#使用反射加载程序集Assembly。load()使用全过程
- Unity热更新之C#反射加载程序集
- c#反射中Assembly类动态加载程序集
- Unity3D热更新之C#反射加载程序集
- CUDA教程
- 内存泄露与检测工具
- Loner_li 面向对象 实例练习--要求:用户输入上述四个字段的值,实例化一个Computer类,然后调用类中方法输出电脑详细信息
- 母函数详解
- 黑马程序员——交通灯管理系统
- 谈谈:程序集加载和反射
- 如何分析一个存储过程的性能
- MediaPlayer取得音视频文件总时长的方法
- MyEclipse中关闭项目的作用及操作方法
- c++虚基类
- poj1190生日蛋糕(dfs+剪枝)
- 在内核里添加yaffs2的支持
- .net学习网址
- ios开发ASIHTTPRequest-进度追踪