news 2026/2/1 22:14:13

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/29 23:55:44

StreamCap终极指南:如何轻松实现多平台直播自动录制

StreamCap终极指南:如何轻松实现多平台直播自动录制 【免费下载链接】StreamCap 一个多平台直播流自动录制工具 基于FFmpeg 支持监控/定时/转码 项目地址: https://gitcode.com/gh_mirrors/st/StreamCap 想要不错过任何一场精彩直播?StreamCap跨…

作者头像 李华
网站建设 2026/2/1 4:09:54

Figma中文插件终极指南:3步告别语言障碍

Figma中文插件终极指南:3步告别语言障碍 【免费下载链接】figmaCN 中文 Figma 插件,设计师人工翻译校验 项目地址: https://gitcode.com/gh_mirrors/fi/figmaCN 还在为Figma的英文界面头疼不已?每次操作都要查词典,专业术语…

作者头像 李华
网站建设 2026/1/29 18:01:37

UE5视频处理终极指南:InVideo插件从入门到精通的完整教程

UE5视频处理终极指南:InVideo插件从入门到精通的完整教程 【免费下载链接】InVideo 基于UE4实现的rtsp的视频播放插件 项目地址: https://gitcode.com/gh_mirrors/in/InVideo 在当今的游戏开发领域,UE5视频处理已成为提升用户体验的关键技术。InV…

作者头像 李华
网站建设 2026/1/30 15:27:13

5分钟极速上手Figma中文界面:设计师的翻译神器使用指南

5分钟极速上手Figma中文界面:设计师的翻译神器使用指南 【免费下载链接】figmaCN 中文 Figma 插件,设计师人工翻译校验 项目地址: https://gitcode.com/gh_mirrors/fi/figmaCN 还在为Figma英文界面而烦恼吗?作为国内设计师&#xff0c…

作者头像 李华
网站建设 2026/1/29 17:39:37

Windows热键冲突检测全攻略:快速定位快捷键占用程序

Windows热键冲突检测全攻略:快速定位快捷键占用程序 【免费下载链接】hotkey-detective A small program for investigating stolen hotkeys under Windows 8 项目地址: https://gitcode.com/gh_mirrors/ho/hotkey-detective 🎯 你是否经历过按下…

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

Windows 11任务栏拖放功能如何恢复?3步搞定系统体验升级

Windows 11任务栏拖放功能如何恢复?3步搞定系统体验升级 【免费下载链接】Windows11DragAndDropToTaskbarFix "Windows 11 Drag & Drop to the Taskbar (Fix)" fixes the missing "Drag & Drop to the Taskbar" support in Windows 11.…

作者头像 李华