第二十三章 程序集加载和反射

23.1 程序集加载

JIT编译器将方法的IL代码编译成本机代码时,会查看IL代码中引用了哪些类型。在运行时,JIT编译器利用程序集的TypeRef和AssemblyRef元数据表来肯定哪个程序集定义了全部引用的类型。数组

经过Assembly的Load方法加载程序集。安全

23.2 使用反射构建动态可扩展应用程序

 类库须要理解类型的定义才能提供丰富的功能,就适合使用反射。性能

应用程序须要从特定程序集中加载特定类型以执行特定任务时,也要使用反射。 线程

23.3 反射的性能

 缺点:设计

反射形成编译时没法保证类型安全性。对象

反射速度慢。接口

使用反射调用成员也会影响性能。用反射调用方法时,首先必须将实参打包成数组;在内部,反射必须将这些实参解包到线程栈上。进程

最好避免利用反射来访问字段或调用方法/属性。因使用:事件

让类型从编译时已知的基类型派生。内存

让类型实现编译时已知的接口。

3.1 发现程序集中定义的类型

3.2 类型对象的准确含义

3.3 构建Exception派生类型的层次结构

3.4 构造类型的实例

  得到对Type派生对象的引用以后,就能够构造该类型的实例了。

System.Activator的CreateInstance方法

System.Activator的CreateInstanceFrom方法

System.AppDomain的方法

System.Reflection.ConstructorInfo的Invoke实例方法

23.4 设计支持加载项的应用程序

构建可扩展应用程序时,接口时是中心。可用基类型代替接口,但接口一般是首选,由于它容许加载项开发人员选择他们本身的基类。设计:

  建立“宿主SDK”(Host SDk)程序集,它定义了一个接口,接口的方法做为宿主应用程序与加载项之间的通讯机制使用。为接口方法参数和返回类型时,请尝试使用MSCorLib.dll中定义的其余接口或类型。要传递并返回本身的数据类型,也在“宿主SDK”程序集定义。一旦搞定接口定义,就可为这个程序集赋予强名称,而后把它打包并部署到合做伙伴和用户那里。

  加载项开发人员会在加载项程序集中定义本身的类型。这些程序集将引用你的“宿主”程序集中的类型 。

  建立单独的“宿主应用程序”程序集,在其中包含你的应用程序类型。这个程序集显然要引用“宿主SDK”程序集,并使用其中定义的类型。

23.5 使用反射发现类型的成员

 5.1 发现类型的成员

MemberInfo的全部派生类型都通用的属性和方法

成员名称 成员类型 说明
Name 一个string属性 返回成员名称
DeclaringType 一个Type属性 返回声明成员的Type
Module 一个Module属性 返回声明成员的Module
CustomAttributes 该属性返回一个IEnumerable<CustomAtrributeData>

返回一个集合,其中每一个元素都标识了应用该成员的一个定制特性的实例。

 

5.2  调用类型的成员

如何调用成员

 成员类型 调用成员而须要调用的方法 
 FiledInfo

调用GetValue获取字段的值

调用SetValue设置字段的值 

 ConstructorInfo 调用Invoke构造类型的实例并调用构造器 
 MethodInfo 调用Invoke来调用类型的方法 
 PropertyInfo

调用GetValue来调用的属性的get访问器方法

调用SetValue来调用属性的set访问器方法 

EventInfo

调用AddEventHandler来调用事件的add访问器方法

调用RemoveEventHanlder来调用事件的remove访问器方法

 

5.3 使用绑定句柄减小进程的内存消耗

许多应用程序都绑定了一组类型(Type对象)或类型呢成员(MemberInfo派生对象),并将这些对象保存在某种形式的集合中。

开发人员可使用运行时句柄代替对象以减小工做集(占用得内存)。RuntimeTypeHandle.RuntimeFieldHandle和RuntimeMethodHandle三个类型,包含一个字段“IntPtr”,IntPtr字段是一个句柄,引用了AppDomain的Loader堆中的一个类型,字段或方法。

相关文章
相关标签/搜索