第 23 章 程序集加载和反射 程序集的加载
- Assembly.Load 加载程序集
- Assembly.LoadFrom 加载指定路径名的程序集,内部原理就是通过GetAssemblyName获取程序集名,再利用Assembly.Load来加载,PS:这个路径可以是URL格式的
- 通过字符串来标识类、成员字段、函数等,通过扫描元数据表进行大量的字符串搜索比较
- 通过反射调用方法,需要将实参打包成数组,然后在线程栈解包,检查实参的正确类型,调用者权限等
- 可以使用一下方法来避免直接调用函数
- 反射的类型派生自编译时已知类型,运行时构造反射类型实例,将对他的引用放到基类变量中,然后调用基类方法
- 反射的类型实现编译是已知接口,运行时构造反射类型实例,将对他的引用放到基类变量中,然后调用基类方法
- Assembly.ExportedTypes 程序集所有public类型
- 程序集中每个类型只有一个Type所有Type类型可以用==判断
- System.Activator.CreateInstance
- System.Activator.CreateInstanceFrom 参数为string 返回ObjectHandle,需要调用Unwrap具体化
- System.AppDomain实例方法CreateInstanceFrom AppDomain实例方法,指定在哪个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>();
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);
}



