C# 反射(Reflection)超全解析

C# 高级--反射 详解 C#来自于System.Reflection,是一个帮助类库,可以读取dll/exe中metadata,使用metadata创建对象。获取方法MethodInfo,执行MethodInfo 的Invoke方法,传递方法所在的类的实例对象+参数。需要传递一个object类型的数组作为参数,参数按照从昨往右严格匹配,如果没有匹配的报异常。中间语言,编译把高级语言编译后得到的C#中最真实的语言状态,面向对象语言。需要通过方法参数类型类区别方法,传递参数,严格匹配参数类型。一种反射技术,可以动态创建dll/exe。 阅读详情

一、反射(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. 类型判断
  • IsInterface、IsArray、IsPrimitive、IsEnum
  • IsClass、IsPublic
2. 类型信息
  • Name(类型名)、FullName(完整类型名)、BaseType(基类)
3. 类型关系判断
  • IsInstanceOfType(object obj)
  • IsAssignableFrom(Type type)
4. 成员获取
  • GetConstructor(Type[] paramTypes)
  • GetMethod(string name, Type[] paramTypes)
  • GetProperty(string name)

基础示例

Type type = 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

Type type = typeof(Person);
foreach (MemberInfo member in type.GetMembers())
{
    Console.WriteLine(member.Name + " - " + member.MemberType);
}

运行结果示例:

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

2. MethodInfo(方法反射)

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

运行结果:

Hi, my name is chen
调用带参数方法
MethodInfo method2 = type.GetMethod(
    "SayHi",
    new Type[] { typeof(string) }
);

method2.Invoke(personObj, new object[] { "Tom" });

运行结果:

Hi, Tom

3. ConstructorInfo(构造函数反射)

ConstructorInfo ctor = type.GetConstructor(Type.EmptyTypes);
object obj = ctor.Invoke(null);

等价于:

object obj = Activator.CreateInstance(type);

4. PropertyInfo(属性反射)

PropertyInfo prop = type.GetProperty("Name");

// 设置值
prop.SetValue(obj, "chen");

// 获取值
string name = (string)prop.GetValue(obj);

输出:

chen

六、完整反射综合示例

using System;
using System.Reflection;

class Program
{
    static void Main()
    {
        Type type = typeof(Person);

        // 创建实例
        object obj = Activator.CreateInstance(type);

        // 设置属性
        PropertyInfo prop = type.GetProperty("Name");
        prop.SetValue(obj, "chen");

        // 调用无参方法
        MethodInfo m1 = type.GetMethod("SayHi");
        m1.Invoke(obj, null);

        // 调用带参方法
        MethodInfo m2 = type.GetMethod(
            "SayHi",
            new[] { typeof(string) }
        );
        m2.Invoke(obj, new object[] { "Jack" });
    }
}

class Person
{
    public string Name { get; set; }

    public void SayHi()
    {
        Console.WriteLine($"Hi, my name is {Name}");
    }

    public void SayHi(string name)
    {
        Console.WriteLine($"Hi, {name}");
    }
}

运行结果:

Hi, my name is chen
Hi, Jack

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

1. 拷贝方法(浅拷贝)

static object MyClone(object source)
{
    if (source == null)
        throw new ArgumentNullException(nameof(source));

    Type type = source.GetType();
    object target = Activator.CreateInstance(type);

    foreach (PropertyInfo prop in type.GetProperties())
    {
        if (prop.CanRead && prop.CanWrite)
        {
            prop.SetValue(target, prop.GetValue(source));
        }
    }

    return target;
}

2. 验证代码

Person p1 = new Person { Name = "chen", Age = 12 };
Person p2 = (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. 类型安全

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

十、总结(工程视角)

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

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

C#反射(Reflection) (能够通过非反射方式实现的功能,尽量不要用反射)反射是.NET中的重要机制,通过反射可以得到*.exe或*.dll等程序集内部的接口、类、方法、字段、属性、特性等信息,还可以动态创建出类型实例并执行其中的方法。反射的定义:审查元数据并收集关于它的类型信息的能力。元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等。Reflection,中文翻译为反射。 阅读详情

相关推荐

C# 反射(Reflection)

C#反射(Reflection)

xiaoaque的博客 975

c#之反射详解

C#之反射详解

鲤籽鲲的博客 2万+

C# 反射(Reflection)总结

反射是.NET Framework 的功能,并不是C#语言特有的功能。简单理解来看就是:给我一个对象,我能,也不知道是什么静态类型的情况下,创建一个同类型的对象,同时还能访问这个对象的各个成员。(在获取其他实体类的字段名或实列,只能获取公有的,而有了反射之后可以获取私有的,可以获取他的基类等等,可以说把家底查得清清楚楚。

明月清风@的博客 2272

C# 中的反射机制

- 可以使用反射动态创建类型的实例,讲类型绑定到现有对象,或从现有对象中获取类型,然后调用其方法或访问器字段和属性。 - 反射可以理解为操作metadata的一个类库(将反射当作工具使用,用于读取或者操作元数据)

KamikazePilot的博客 1827

C#的反射

一、反射介绍 反射:指程序可以访问、检测和修改它本身状态或行为的一种能力(即:审查元数据并收集关于它的类型信息的能力) ①元数据(编译以后的最基本数据单元)可以理解为一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等。 ②反射则提供了封装程序集、模块和类型的对象(程序集包含模块,而模块包含类型,类型又包含成员【成员--->类型--->模块--->程序集】)。 ③可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象..

提供C#相关开发 、云计算、运维测试、网络安全相关技术分享与服务,有意向可联系。 1万+

详解C#反射(Reflection)

详解C#反射的概念和用法

ellis1970的博客 2090

C#高级--反射详解

C#高级–反射详解 一、什么是反射/反编译 1、C#编译运行过程 高级语言->编译->dll/exe文件->CLR/JIT->机器码 2、原理解析 metadata:元数据数据清单,记录了dll中包含了哪些东西,是一个描述。 IL:中间语言,编译把高级语言编译后得到的C#中最真实的语言状态,面向对象语言。 反射:来自于System.Reflection,是一个帮助类库,可以读取dll/exe中metadata,使用metadata创建对象。 Emit:一种反射技术,可以动态创建dl

李宥的博客 3万+

C#中反射(Reflection)的详细介绍

C#反射技术主要基于System.Type类和System.Reflection.Assemble类,通过Type类可以访问关于任何数据类型的信息,Assemble类用于访问给定程序集的相关信息,或把这个程序集加载到程序中。GetCustomAttributes方法用于获取程序集的特性,他有两个重载方法:如果在调用它时,除了程序集的引用外,没有其它参数,该方法就会返回这个程序集定义的所以自定义特性;

仰望星空的博客 1279

C# 反射(Reflection)超详细解析

C# 反射(Reflection)超详细解析

明明明的博客 2万+

C#反射(Reflection)详解

C#反射(Reflection)详解 什么是反射 命名空间和装配体的关系

从Live2D到Unreal Engine:2D与3D虚拟数字人核心技术实现路径解析

本文深入解析了从Live2D到Unreal Engine的2D与3D虚拟数字人核心技术实现路径,涵盖技术选型、制作流程与优化技巧。通过对比2D骨骼动画与3D建模渲染的差异,结合实战案例,帮助开发者根据项目需求选择合适方案,提升虚拟数字人的交互体验与视觉效果。

weixin_30379531的博客 149

29.C# 反射(Reflection)——《跟老吕学C#》

反射是C#编程中一种强大的工具,它允许程序在运行时检查对象或类型的元数据,并动态地创建和操作这些对象。通过反射,我们可以检查对象类型、动态创建实例、获取和设置属性和字段、动态调用方法等。然而,反射也有一些缺点,包括性能问题和安全性风险。因此,在使用反射时,需要权衡其带来的好处和潜在的负面影响,并采取相应的优化和安全措施来降低这些风险。尽管存在这些限制,但反射仍然是实现某些功能(如插件系统或可扩展应用程序)所必需的。通过谨慎使用和优化反射操作,我们可以充分利用其强大的功能来构建灵活、可扩展的应用程序。

Python老吕的博客 1404

Keil5编译报错:ARM Compiler Version 5缺失的完整解决方案

本文提供了Keil5编译报错“ARM Compiler Version 5缺失”的完整解决方案。详细介绍了手动安装ARM Compiler Version 5的步骤,包括下载安装包、配置编译器路径及常见问题排查,帮助开发者快速恢复老项目的编译环境。

bb456的博客 945

C#反射(Reflection)的概念和用法详解

C#反射(Reflection)的概念和用法详解 1、 什么是反射 2、 命名空间与装配件的关系 3、 运行期得到类型信息有什么用 4、 如何使用反射获取类型 5、 如何根据类型来动态创建对象 6、 如何获取方法以及动态调用方法 7、 动态创建委托 1、什么是反射         Reflection,中文翻译为反射。         这是.Net中

天生爱赞美的博客 4918

AD9361 Fast Lock实战:Python脚本自动生成Profile寄存器配置(附完整代码)

本文详细介绍了利用Python脚本实现AD9361 Fast Lock Profile寄存器自动化配置的实战方案。通过解析频率合成公式、VCO约束及查表机制,脚本能根据目标频率一键生成完整的16进制寄存器序列,大幅提升射频系统开发中多频点切换的效率和准确性,并支持CSV、JSON、C头文件等多种输出格式,便于与FPGA/嵌入式系统集成。

weixin_29194693的博客 475

Python爬虫获取Shopee店铺的所有商品?

通过上述代码示例,我们可以轻松实现获取Shopee店铺所有商品信息的功能。Python爬虫不仅具有强大的功能和稳定性,还可以通过丰富的库支持实现高效的数据抓取和解析。希望这篇文章能为你提供一些启发和帮助。如果你对爬虫开发有更多兴趣,可以尝试探索更复杂的功能,如多线程爬取、数据可视化等。如果你在实践中遇到任何问题,欢迎随时交流和讨论。让我们一起用技术的力量,解锁更多可能!

2401_87195067的博客 1543

【C#进阶】C# 反射

关于编程语言 C# 反射的介绍。

好学若饥,谦卑若愚。 3112

openEuler系统下安装Google Chrome浏览器全攻略(附依赖问题解决方案)

本文详细介绍了在openEuler系统上安装Google Chrome浏览器的完整指南,包括环境准备、多种安装方式、依赖问题解决方案及性能优化技巧。针对openEuler特有的软件生态和依赖管理机制,提供了实用的命令和配置方法,帮助用户克服安装过程中的常见障碍,实现流畅的Chrome使用体验。

hadoop5ranger的博客 1148

Reflection反射【C#】

【代码】反射Reflection。

cfqq1989的博客 2448

Unity中URP实现水体效果(泡沫)

在上篇文章中,我们实现了水体的深度。在这篇文章中,我们来使用上篇文章采样后的深度图来实现水中的泡沫效果。

楠溪泽岸的博客 3489

【NLP】第10章 使用基于 BERT 的 Transformer 进行语义角色标记

Transformers 在过去几年里取得的进步比上一代 NLP 还要多。标准 NLU 方法首先学习句法和词汇特征来解释句子的结构。在运行语义角色标签( SRL )之前,将训练以前的 NLP 模型理解语言的基本语法。Shi和Lin(2019)在他们的论文开始时询问是否可以跳过初步的句法和词汇训练。基于 BERT 的模型可以在不经过那些经典训练阶段的情况下执行 SRL 吗?答案是肯定的!Shi和Lin (2019) 建议 SRL 可以被视为序列标记并提供标准化的输入格式。他们基于 BERT 的模型产生了令人惊

sikh_0529的博客 7374

[C#]C# 反射(Reflection)

反射提供描述程序集、模块和类型的对象(Type 类型)。可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型,然后调用其方法或访问器字段和属性。如果代码中使用了特性(Attribute),可以利用反射来访问它们。本文主要介绍C# 反射(Reflection)。

FL1768317420的博客 804

【SpringBoot 3.x 第51节】带你玩转 GraalVM Native Image:启动快到飞起,内存省到心疼,你还不试试?

🏆本文收录于《滚雪球学SpringBoot 3》,专门攻坚指数提升,本年度国内最系统+最专业+最详细(永久更新)。    本专栏致力打造最硬核 SpringBoot3 从零基础到进阶系列学习内容,🚀均为全网独家首发,打造精品专栏,专栏持续更新中…欢迎大家订阅持续学习。 如果想快速定位学习,可以看这篇【SpringBoot3教程导航帖】,你想学习的都被收集在内,快速投入学习!!两不误。    若还想学习更多,可直接前往《滚雪球学SpringBoot(全版本合集)》,涵盖SpringBoot所有版本教学文章

**My Coding Family** 1304
上一篇: 吃透 ADO.NET 核心对象,轻松搞定数据库操作
下一篇: .NET 核心:Func 与 Action 委托(从入门到实战)
bugcome_com
博客等级 码龄3年 32粉丝 131原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bugcome_com

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值