news 2026/1/27 14:20:49

C# 反射(Reflection)超全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C# 反射(Reflection)超全解析

一、反射(Reflection)的清晰定义

反射(Reflection)是 .NET 框架提供的核心运行时机制,它允许程序在运行时而非编译时

  • 获取程序集(Assembly)、模块(Module)、类型(Type)的元数据信息
  • 动态创建对象实例
  • 动态调用方法
  • 动态读取或修改属性/字段
  • 动态解析自定义特性(Attribute)

对比理解

方式特点
普通编码编译期确定类型,直接调用,性能高
反射编程运行期确定类型,动态操作,极度灵活

通俗理解

  • 普通编程:编译期就确定要使用哪个类、调用哪个方法,代码是“写死的”。
  • 反射编程:程序运行时才知道要操作哪个类,通过读取元数据“动态操作类型”。

👉一句话:反射 = 运行时读取元数据 + 动态操作类型


二、.NET 中反射的底层基础

IL 与元数据

  • C# → 编译 →IL(中间语言)
  • 同时生成Metadata(元数据表)(包含类型名、命名空间、成员签名、特性信息等)

反射的本质:

读取程序集中的 Metadata,而不是“反编译源码”


三、反射核心类继承体系与关键成员

1. 核心类继承结构

MemberInfo ├── FieldInfo ├── PropertyInfo ├── MethodBase │ ├── ConstructorInfo │ └── MethodInfo └── EventInfo

MemberInfo是所有“成员描述类”的抽象基类。

2. 各核心类的关键成员(常用)

类名核心父类关键成员作用说明
MemberInfo-Name、GetCustomAttributes()获取成员名称、自定义特性
MethodBaseMemberInfoIsAbstract、IsPublic、IsStatic、Invoke()判断方法特性、调用方法或构造函数
ConstructorInfoMethodBaseInvoke(object[] parameters)调用构造函数创建实例
MethodInfoMethodBaseReturnType、Invoke()获取返回值类型、调用方法
PropertyInfoMemberInfoCanRead、CanWrite、PropertyType、GetValue()、SetValue()获取/设置属性值

四、Type 类深度解析(核心入口)

Type是整个反射体系的入口类,几乎所有反射操作都从它开始。

常用成员

1. 类型判断
  • IsInterfaceIsArrayIsPrimitiveIsEnum
  • IsClassIsPublic
2. 类型信息
  • Name(类型名)、FullName(完整类型名)、BaseType(基类)
3. 类型关系判断
  • IsInstanceOfType(object obj)
  • IsAssignableFrom(Type type)
4. 成员获取
  • GetConstructor(Type[] paramTypes)
  • GetMethod(string name, Type[] paramTypes)
  • GetProperty(string name)

基础示例

Typetype=typeof(Person);Console.WriteLine(type.Name);Console.WriteLine(type.FullName);Console.WriteLine(type.BaseType);Console.WriteLine(type.IsClass);Console.WriteLine(type.IsPublic);

运行结果:

Person ReflectionDemo.Person System.Object True True

五、核心反射类型详解(附示例)

1. MemberInfo

Typetype=typeof(Person);foreach(MemberInfomemberintype.GetMembers()){Console.WriteLine(member.Name+" - "+member.MemberType);}

运行结果示例:

get_Name - Method set_Name - Method SayHi - Method Name - Property

2. MethodInfo(方法反射)

获取并调用无参方法
MethodInfomethod=type.GetMethod("SayHi");method.Invoke(personObj,null);

运行结果:

Hi, my name is chen
调用带参数方法
MethodInfomethod2=type.GetMethod("SayHi",newType[]{typeof(string)});method2.Invoke(personObj,newobject[]{"Tom"});

运行结果:

Hi, Tom

3. ConstructorInfo(构造函数反射)

ConstructorInfoctor=type.GetConstructor(Type.EmptyTypes);objectobj=ctor.Invoke(null);

等价于:

objectobj=Activator.CreateInstance(type);

4. PropertyInfo(属性反射)

PropertyInfoprop=type.GetProperty("Name");// 设置值prop.SetValue(obj,"chen");// 获取值stringname=(string)prop.GetValue(obj);

输出:

chen

六、完整反射综合示例

usingSystem;usingSystem.Reflection;classProgram{staticvoidMain(){Typetype=typeof(Person);// 创建实例objectobj=Activator.CreateInstance(type);// 设置属性PropertyInfoprop=type.GetProperty("Name");prop.SetValue(obj,"chen");// 调用无参方法MethodInfom1=type.GetMethod("SayHi");m1.Invoke(obj,null);// 调用带参方法MethodInfom2=type.GetMethod("SayHi",new[]{typeof(string)});m2.Invoke(obj,newobject[]{"Jack"});}}classPerson{publicstringName{get;set;}publicvoidSayHi(){Console.WriteLine($"Hi, my name is{Name}");}publicvoidSayHi(stringname){Console.WriteLine($"Hi,{name}");}}

运行结果:

Hi, my name is chen Hi, Jack

七、反射实现通用对象拷贝(完整 + 验证)

1. 拷贝方法(浅拷贝)

staticobjectMyClone(objectsource){if(source==null)thrownewArgumentNullException(nameof(source));Typetype=source.GetType();objecttarget=Activator.CreateInstance(type);foreach(PropertyInfopropintype.GetProperties()){if(prop.CanRead&&prop.CanWrite){prop.SetValue(target,prop.GetValue(source));}}returntarget;}

2. 验证代码

Personp1=newPerson{Name="chen",Age=12};Personp2=(Person)MyClone(p1);p2.Name="zhangsan";Console.WriteLine(p1.Name);Console.WriteLine(p2.Name);

运行结果:

chen zhangsan

特点说明

  • ✅ 支持任意对象、不依赖具体类型
  • ❌ 仅实现浅拷贝
  • ❌ 要求目标类型有无参构造函数

八、反射的典型使用场景(工程级)

1. 框架与底层组件

  • ORM(EF Core、Dapper)
  • 依赖注入(Autofac)
  • 序列化(Newtonsoft.Json、System.Text.Json)

2. 插件化架构

  • 动态加载 DLL
  • 运行时发现并执行模块

3. 通用基础工具

  • 对象拷贝
  • 表单/模型验证
  • 通用 Mapper

九、反射的代价、注意事项与优化方案

1. 性能问题

  • 反射 ≈ 普通调用的5~20 倍开销
  • 优化方案:
    • 缓存Type / MethodInfo / PropertyInfo等反射对象
    • 结合表达式树(Expression)优化
    • 使用Delegate.CreateDelegate转为委托调用

2. 封装性破坏

  • 反射可绕过访问修饰符访问私有成员
  • 建议:框架级场景使用,业务层慎用

3. 类型安全

  • 编译期无法校验反射操作的类型正确性
  • 必须做好异常处理(如NullReferenceExceptionMissingMethodException等)

十、总结(工程视角)

  • 反射是 .NET 框架能力的地基,是框架的灵魂
  • 核心入口:Type类;核心成员描述类:MethodInfo / PropertyInfo / ConstructorInfo
  • 优点:高度灵活、解耦,框架开发必备
  • 缺点:性能损耗、类型不安全、破坏封装性
  • 业务代码应“少而精”使用,框架代码必须掌握

反射不是为了偷懒,而是为了“抽象与解耦”。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/23 2:47:05

Android Studio中文界面深度优化指南:从英文困扰到母语开发体验

Android Studio中文界面深度优化指南:从英文困扰到母语开发体验 【免费下载链接】AndroidStudioChineseLanguagePack AndroidStudio中文插件(官方修改版本) 项目地址: https://gitcode.com/gh_mirrors/an/AndroidStudioChineseLanguagePack 还在为…

作者头像 李华
网站建设 2026/1/22 14:23:25

机械键盘连击修复终极指南:零成本软件方案完整解析

机械键盘连击修复终极指南:零成本软件方案完整解析 【免费下载链接】KeyboardChatterBlocker A handy quick tool for blocking mechanical keyboard chatter. 项目地址: https://gitcode.com/gh_mirrors/ke/KeyboardChatterBlocker KeyboardChatterBlocker防…

作者头像 李华
网站建设 2026/1/15 12:15:58

Qwen3Guard-Gen-8B能否识别非法集会组织的线上号召信息?

Qwen3Guard-Gen-8B能否识别非法集会组织的线上号召信息? 在社交媒体深度渗透公共生活的今天,一条看似平常的群聊消息——“周末大家出来聚聚吧”——背后可能隐藏着远超字面意义的风险。当这类表达被用于组织未经批准的集体行动时,传统的关键…

作者头像 李华
网站建设 2026/1/20 9:56:04

鸣潮性能优化终极配置指南:WaveTools完全使用手册

鸣潮性能优化终极配置指南:WaveTools完全使用手册 【免费下载链接】WaveTools 🧰鸣潮工具箱 项目地址: https://gitcode.com/gh_mirrors/wa/WaveTools 还在为《鸣潮》游戏运行卡顿、帧率不稳而苦恼?想要获得丝滑流畅的120帧游戏体验却…

作者头像 李华
网站建设 2026/1/13 1:56:14

思源宋体CN完全手册:7款专业字重免费开源字体使用指南

思源宋体CN完全手册:7款专业字重免费开源字体使用指南 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 思源宋体CN是由Adobe与Google联合打造的开源中文字体,为中…

作者头像 李华
网站建设 2026/1/11 16:33:38

突破Windows 11限制:智能任务栏拖放功能完全恢复指南

突破Windows 11限制:智能任务栏拖放功能完全恢复指南 【免费下载链接】Windows11DragAndDropToTaskbarFix "Windows 11 Drag & Drop to the Taskbar (Fix)" fixes the missing "Drag & Drop to the Taskbar" support in Windows 11. It…

作者头像 李华