前面介绍了程序集加载的一般方式,但是我们的目的往往并不是简单的载入程序集就结束了,我们还希望了解程序集包含了哪些类型,借助程序集的某些类型实现想要的功能等。下面就接着前一章的内容继续向下学习。
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);
总结:基本理解的套路是程序集加载,类型发现,对象构造。