前面介绍了程序集加载的一般方式,但是我们的目的往往并不是简单的载入程序集就结束了,我们还希望了解程序集包含了哪些类型,借助程序集的某些类型实现想要的功能等。下面就接着前一章的内容继续向下学习。

    1.发现程序集中定义的类型。常用的方法是Assembly的GetExportedTypes

1   Assembly assemblyFromPath = Assembly.LoadFile(@"E:\StrongNameDLL.dll");
2   foreach (Type t in assemblyFromPath.GetExportedTypes())
3   {
4       if (t.GetType() == typeof(FileInfo))
5       { ... }
6       if (t.GetType() == typeof(MethodInfo))
7       { ... }
8   }

注意,GetExportedTypes返回的是System.Type对象构成的一个数组。而System.Type是一个从System.Reflection.MemberInfo派生的抽象基类,它是执行类型和对象操作的起点。


   2.类型对象的准确含义

   在上述代码的遍历中,使用操作符typeof,将晚期绑定的类型信息与早期绑定(编译时已知)的类型信息进行精确匹配(非兼容匹配),找准类型对象的准确含义,进而执行自己想要的操作。

 

   3.构造类型的实例

   拥有对一个Type派生对象的引用之后,就可以构造该类型的一个实例了。FCL提供了以下几种机制。

   •System.Activator的CreateInstance方法

   a.参数可以传递一个Type对象的引用,也可以传递标识了想要创建的类型的一个String

   b.传递Type对象的引用,返回的是对新对象的一个引用

   c.传递字符串的方式,返回的是一个System.Runtime.Remoting.ObjectHandle对象(派生自System.MarshalByRefObject)。

   d.传递字符串的方式,首先,必须指定另一个字符串来标识定义了类型的那个程序集;其次,如果正确配置了远程访问选项,还允许构造远程对象;使用ObjectHandle的Unwrap方法进行具体化

 

   •System.Activator的CreateInstanceFrom方法

   a.必须通过字符串来指定类型及其程序集

   b.程序集要用Assembly的LoadFrom方法加载到调用的AppDomain中

   c.返回的都是ObjectHandle对象引用

   d.使用ObjectHandle的Unwrap方法进行具体化

1 System.Runtime.Remoting.ObjectHandle oh = 
2 Activator.CreateInstanceFrom(Assembly.GetEntryAssembly().CodeBase, 
3                                  typeof(SomeType).FullName);
4 
5 SomeType st = (SomeType) oh.Unwrap();
6 st.DoSomething(5);

 

   •System.AppDomain方法

   a.提供4个用于构造类型实例的实例方法:CreateInstance,CreateInstanceAndUnwrap, CreateInstanceFrom, CreateInstanceFromAndUnwrap

   b.方法行为与Activator类的方法相似,只是它们都是实例方法

   c.允许指定在哪个AppDomain中构造对象

 

   •System.Type的InvokeMember实例方法

   a.查找与传递的实参匹配的一个构造器,并构造类型

   b.类型总是在调用AppDomain中创建,返回的是对新对象的一个引用

 

   •System.Reflection.ConstructorInfo的Invoke实例方法

   a.Type对象的引用绑定到一个特定的构造器,获取对构造器的ConstructorInfo对象的一个引用

   b.利用ConstructorInfo对象的引用调用Invoke方法

   c.在调用AppDomain中创建,返回的是对新对象的一个引用

 

   4.其他机制

   上述机制,可以为除了数组和委托之外的所有类型创建一个对象。

   数组:调用Array的静态CreateInstance方法

   委托:调用Delegate的静态CreateDelegate方法

 

   注意:构造泛型类型的实例

   a.获取开放类型引用

   b.调用Type的公共实例方法MakeGenericType

   c.获取返回的Type对象,传给实例构造方法

1 Type openType = typeof(Dictionary<,>);
2 
3 Type closeType = openType.MakeGenericType(typeof(String), typeof(Int32));
4 
5 object obj = Activator.CreateInstance(closeType);


总结:基本理解的套路是程序集加载,类型发现,对象构造。