应使用 Assembly.LoadFrom() 加载 DLL,再通过 GetType() 获取类型,用 BindingFlags 显式指定访问权限获取非公有成员,缓存 MethodInfo 等反射对象以提升性能,谨慎评估反射必要性。

GetType() 和 typeof() 是获取类型信息最直接的方式,但它们只适用于编译期已知类型的场景;真正在运行时动态探查未知类型、加载程序集后解析类结构、或实现插件机制时,必须依赖 Assembly + Type + MemberInfo 这套反射组合。
怎么从 DLL 文件里加载并检查一个类?
不能直接用 typeof(MyClass) —— 那个类根本不在当前程序集里。得先用 Assembly.LoadFrom() 把 DLL 载入内存,再用 GetTypes() 或 GetType(string) 定位目标类型。
-
Assembly.LoadFrom("plugin.dll")会触发 JIT 加载,失败时抛FileLoadException或BadImageFormatException(比如 x64 程序加载了 x86 DLL) -
assembly.GetType("PluginNS.MyProcessor")的参数是完整命名空间+类名,不带文件扩展名,大小写敏感 - 如果 DLL 有强名称且未 GAC 注册,建议改用
Assembly.Load(AssemblyName)配合AssemblyResolve事件处理依赖缺失
为什么 type.GetMethods() 拿不到 private 方法?
默认只返回 public 成员。要访问非公开成员,必须显式传入 BindingFlags 参数,否则连 private 字段、internal 构造函数都不可见。
- 常用组合:
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance - 漏掉
BindingFlags.DeclaredOnly会导致继承链上的方法也被列出来,干扰筛选 -
GetProperties(BindingFlags)同理,get_*/set_*方法不会自动合并成 PropertyInfo,得靠GetProperty()才能拿到封装后的属性对象
调用 MethodInfo.Invoke() 报 “Object does not match target type” 怎么办?
错误本质是:你传给 Invoke() 的第一个参数(即 obj)类型和该方法声明所在的类型不一致。比如用 string 实例去调用定义在 FileStream 上的 Read() 方法。
- 静态方法必须传
null作第一个参数,传任何实例都会报这个错 - 实例方法必须传对应类型的实例(或其子类),不能传父类引用后期望它“自动转成子类”
- 参数数组
object[]里的每个元素类型要严格匹配方法签名,值类型需装箱,ref/out参数要用TypedReference或改用MethodBase.Invoke()配合ParameterInfo.IsOut判断
反射性能差,哪些地方最容易拖慢?
不是所有反射操作都慢:typeof() 和 GetType() 是零开销;真正昂贵的是 GetMethod() 查找、Invoke() 执行、以及反复调用 GetCustomAttributes() 解析特性。
- 避免在循环里反复调用
type.GetMethod("DoWork")—— 提前缓存MethodInfo对象 -
Activator.CreateInstance(type)比type.GetConstructor(...).Invoke(args)快,但无法指定构造函数重载;若需控制构造逻辑,建议用Expression.Lambda编译委托替代反复Invoke -
Attribute.GetCustomAttribute()内部会做反射查找+实例化,高频场景下应预提取并缓存结果,或改用源生成器(Source Generator)在编译期生成元数据访问代码
真正难的不是怎么写反射代码,而是判断“这里到底该不该用反射”。比如配置驱动的策略路由、运行时类型适配、序列化框架底层——这些是合理场景;而仅仅为了少写几个 if-else 就用 type.Name == "User" 分支,反而让类型安全和可维护性崩塌。


















