反射在运行时才有意义,编译期已知类型应优先用typeof或GetType();获取Type对象后,可通过BaseType、GetInterfaces()、GetCustomAttribute()等方法查询类名、基类、接口及自定义特性。

反射不是万能的类型查询工具,它在运行时才有意义;编译期已知类型时硬上 typeof 或 GetType() 反而更安全、更快。
怎么拿到一个类型的完整元数据(比如类名、基类、接口、自定义特性)
核心是用 Type 对象——它本身就是反射的入口。获取方式分三种场景:
- 已知类型(编译期确定):直接用
typeof(MyClass),零开销,推荐优先用 - 已有实例:调用
obj.GetType(),注意值类型装箱不影响结果,但null会抛NullReferenceException - 只知道类型全名(字符串):用
Type.GetType("Namespace.MyClass, AssemblyName"),必须带程序集名称,否则只查当前程序集;返回null很常见——不是拼错就是程序集没加载
拿到 Type 后,查继承链:BaseType 返回父类(object 的父类是 null),GetInterfaces() 返回实现的所有接口(不含继承链上的间接接口);查自定义特性:GetCustomAttribute<t>()</t> 或 GetCustomAttributes(typeof(MyAttr), true),第二个参数控制是否查找继承链上的特性。
为什么 GetProperties() 拿不到 public set 的属性?
默认只返回 public 成员,但“可读”和“可写”是分开控制的。常见误区是以为 public int Age { get; set; } 就一定被列出——其实它会被当成两个成员:get_Age 和 set_Age,而 GetProperties() 只返回属性定义本身。
- 漏掉非 public 属性?加
BindingFlags.NonPublic | BindingFlags.Instance - 想区分只读/只写?检查
PropertyInfo.CanRead和PropertyInfo.CanWrite - 遇到索引器(如
this[int i])?它也是PropertyInfo,但PropertyInfo.GetIndexParameters()返回非空数组
别依赖 GetProperties() 的返回顺序——它不保证与源码声明顺序一致,排序需手动处理。
调用方法时 Invoke() 报错 “TargetInvocationException” 怎么快速定位?
这其实是包装异常:TargetInvocationException.InnerException 才是真实错误。直接吞掉它会导致调试困难。
- 永远先检查
ex.InnerException,而不是只看外层消息 - 参数类型不匹配?
MethodInfo.Invoke()不自动转换,int传long会失败,得用Convert.ChangeType()预处理 - 静态方法传
null当第一个参数;实例方法必须传目标对象(不能传null) - 泛型方法?必须先用
MakeGenericMethod()构造封闭类型,再Invoke()
高频踩坑点:用 MethodInfo.Invoke(null, args) 调静态方法时,如果 args 是 null,会报 TargetException,不是 ArgumentNullException——得传 new object[0]。
反射性能差,哪些操作真该避免?
不是所有反射都慢:typeof、GetType()、Type.IsClass 这些是元数据查询,几乎无开销;真正慢的是动态调用(Invoke)、动态创建实例(Activator.CreateInstance)、反复解析相同类型字符串。
- 缓存
Type、MethodInfo、PropertyInfo对象,别每次重新GetMethod() - 避免在循环里做
Type.GetType("xxx"),提前解析好存字典 - 高频调用场景(如序列化)改用表达式树编译委托,或 .NET 5+ 的
ReflectionContext(有限支持) -
Assembly.GetTypes()会强制加载所有类型元数据,大程序集可能卡顿,按需用DefinedTypes+Where(t => t.Name.Contains("Dto"))过滤
最隐蔽的性能陷阱:用 Attribute.GetCustomAttribute() 查大量类型时,它内部会反复反射构造特性实例;换成 Type.GetCustomAttribute<t>()</t>(.NET Core 2.0+)能跳过部分反射路径。


















