type.gettype("myclass")返回null是因为它只查询已加载程序集,不自动加载dll;必须先用assembly.loadfrom()加载dll,再用assembly.gettype("namespace.myclass")获取类型,注意命名空间完整性和大小写敏感。

反射不是万能的“动态开关”,它在运行时才有意义,编译期写死的类型根本用不上反射;真要动态加载 DLL、调用未知类的方法、或绕过访问修饰符读写字段,才必须走 Assembly.LoadFrom() → Type.GetType() → MethodInfo.Invoke() 这条链。
从 DLL 加载类并调用方法,为什么 Type.GetType("MyClass") 总是返回 null?
因为 Type.GetType(string) 只查当前已加载的程序集(包括 mscorlib 和主程序集),不会自动扫描你扔进 bin 目录的外部 DLL。它不负责文件 I/O,也不触发加载。
- 必须先用
Assembly.LoadFrom("plugin.dll")把 DLL 载入 AppDomain,失败会抛FileLoadException或BadImageFormatException(比如 x64 进程加载了 x86 DLL) - 再用
assembly.GetType("PluginNS.MyProcessor")—— 注意参数是完整命名空间+类名,不带.dll后缀,且大小写敏感 - 如果 DLL 有强名称但没注册到 GAC,
LoadFrom()可能因依赖解析失败而静默失败;此时应改用Assembly.Load(AssemblyName)并配合AppDomain.CurrentDomain.AssemblyResolve事件手动处理缺失依赖
GetMethod() 找不到 private 方法,GetProperties() 拿不到 internal 属性?
默认所有 GetXXX() 方法只返回 public 成员,这是设计使然,不是 bug。想看到非公有成员,BindingFlags 是强制参数,漏掉就等于“没开权限”。
- 要获取 private 方法:用
type.GetMethod("DoWork", BindingFlags.NonPublic | BindingFlags.Instance),不能只传名字 - 要获取 internal 属性:必须加
BindingFlags.NonPublic,因为 IL 中 internal 对应的是Assembly可见性,反射 API 里叫IsAssembly - 漏掉
BindingFlags.DeclaredOnly会导致继承链上的方法/属性也被列出来,干扰筛选;加了它才只看当前类型定义的成员 -
GetProperties()返回的是PropertyInfo数组,但不会自动把get_Name/set_Name合并成一个属性对象;要用GetProperty("Name")才能得到封装后的可读写实例
调用 MethodInfo.Invoke() 报 “Object does not match target type” 怎么办?
错误本质是第一个参数(即 obj)的运行时类型和该方法声明所在的类型不匹配。这不是参数值的问题,而是“谁来调这个方法”的身份错了。
- 静态方法必须传
null作第一个参数;传任何对象都会报这个错 - 实例方法必须传该类型或其子类的实例;传父类引用(哪怕实际是子类对象)也可能失败,因为反射检查的是变量声明类型,不是运行时类型
- 参数数组
object[]中每个元素必须严格匹配方法签名:值类型要装箱,ref/out参数不能直接塞值,得用TypedReference或改用MethodBase.Invoke()+ParameterInfo.IsOut判断后再处理 - 泛型方法需先调
MakeGenericMethod(typeof(int))得到封闭构造方法,再调Invoke();直接对开放泛型调Invoke()会报InvalidOperationException
PropertyInfo.SetValue() 静默失败或抛 TargetException?
最常见原因是没检查 CanWrite。C# 的 get; init;、只读自动属性、private set 但没开 BindingFlags.NonPublic,都会让 SetValue() 失效,而且不总抛异常——有时就默默跳过。
- 务必先判断
propertyInfo.CanWrite,为false时明确跳过或抛自定义异常,别靠 try-catch 捕获TargetException - 给
int属性赋null会触发ArgumentException:“Object of type 'null' cannot be converted to type 'System.Int32'”;要用Nullable.GetUnderlyingType(propertyInfo.PropertyType)判断是否可空,再决定是否允许 null - 批量设属性时,别只用
BindingFlags.Public | BindingFlags.Instance—— 它漏掉internal和protected,甚至在跨程序集且无[InternalsVisibleTo]时连 public 都拿不到;常用组合是BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance - 高频调用场景下,反复
GetProperty()+SetValue()开销极大;应缓存PropertyInfo,或用Expression.Lambda编译成委托,性能可提升 10 倍以上
真正难的从来不是“怎么写反射代码”,而是判断“该不该用反射”——比如只是为了读个配置就去反射私有字段,不如把字段改成 public 或加个 public getter;一旦开始依赖 BindingFlags.NonPublic,就得承担后续版本升级时内部实现变更导致反射失效的风险。











