第 23 章 程序集加载和反射
程序集的加载
Assembly.Load加载程序集Assembly.LoadFrom加载指定路径名的程序集,内部原理就是通过GetAssemblyName获取程序集名,再利用Assembly.Load来加载,PS:这个路径可以是URL格式的
反射的性能
- 通过字符串来标识类、成员字段、函数等,通过扫描元数据表进行大量的字符串搜索比较
- 通过反射
调用方法,需要将实参打包成数组,然后在线程栈解包,检查实参的正确类型,调用者权限等 可以使用一下方法来避免直接调用函数
- 反射的类型派生自
编译时已知类型,运行时构造反射类型实例,将对他的引用放到基类变量中,然后调用基类方法 - 反射的类型实现
编译是已知接口,运行时构造反射类型实例,将对他的引用放到基类变量中,然后调用基类方法
反射发现程序集类型
Assembly.ExportedTypes程序集所有public类型- 程序集中每个类型只有一个Type所有Type类型可以用==判断
构造类型实例
System.Activator.CreateInstanceSystem.Activator.CreateInstanceFrom参数为string 返回ObjectHandle,需要调用Unwrap具体化System.AppDomain实例方法CreateInstanceFromAppDomain实例方法,指定在哪个AppDomain实例化System.Reflection.ConstructorInfo实例方法Invoke- 创建数组
Array.CreateInstance - 创建委托
MethodInfo实例方法CreateDelegate - 创建字典
public static void Main()
{
// 方法1
Type dictType = typeof(Dictionary<,>);
Type makedType = dictType.MakeGenericType(typeof(string), typeof(int));
var dictObj = System.Activator.CreateInstance(makedType);
Console.WriteLine(dictObj.GetType().Name);
// 方法2
var dict = System.Activator.CreateInstance<Dictionary<string, int>>();
dict.Add("abc", 1);
}
反射发现程序集类型的成员
注意一点, Type从MemberInfo派生,TypeInfo从Type派生

Type type = typeof(string);
TypeInfo typeInfo = type.GetTypeInfo();
foreach (var member in typeInfo.DeclaredMembers)
{
if(member is Type)
{
Console.WriteLine($"{member.Name}是嵌套类型");
}
if (member is FieldInfo)
{
Console.WriteLine($"{member.Name}是字段");
}
if (member is MethodInfo)
{
Console.WriteLine($"{member.Name}是方法");
}
if (member is ConstructorInfo)
{
Console.WriteLine($"{member.Name}是构造方法");
}
if (member is PropertyInfo)
{
Console.WriteLine($"{member.Name}是属性");
}
if (member is EventInfo)
{
Console.WriteLine($"{member.Name}是事件");
}
}
- 可以利用TypeInfo的实例方法
GetDeclaredXXX返回对应的XXXInfo MethodInfo可以通过GetParameters获得参数信息数组ParameterInfo
调用类型的成员

使用绑定句柄减少内存消耗
- 原文:
许多应用程序都绑定了一组类型(Type 对象)或类型成员(MemeberInfo 派生对象),并将这些对象保存在某种形式的集合中。以后,应用程序搜索这个集合,查找特定对象,然后调用(invoke)这个对象。这样会占用大量的内存,所以FCL定义三个RuntimeTypeHandle,RuntimeFieldHandle 和 RuntimeMethodHandle里面保存了IntPtr
public static void Main()
{
// RuntimeTypeHandle
Type type = typeof(string);
RuntimeTypeHandle typeHandle = Type.GetTypeHandle(type);
var convertType = Type.GetTypeFromHandle(typeHandle);
// RuntimeMethodHandle
MethodInfo methodInfo = type.GetMethod("Compare");
RuntimeMethodHandle methodHandle = methodInfo.MethodHandle;
var convertMethod = MethodInfo.GetMethodFromHandle(methodHandle);
// RuntimeFieldHandle
FieldInfo fieldInfo = type.GetField("Empty");
RuntimeFieldHandle runtimeFieldHandle = fieldInfo.FieldHandle;
var convertField = FieldInfo.GetFieldFromHandle(runtimeFieldHandle);
}










