当前位置: 首页 > article >正文

C#进阶知识 反射

前言反射可以看透程序的内部构造一什么是反射在 C# 中代码在被编译后会生成一堆“元数据”Metadata。这些元数据记录了这个类叫什么、有哪些属性、有哪些私有方法。常规操作你知道一个类叫Person所以你写new Person()。这叫“编译时”确定。反射操作程序运行的时候你突然拿到一个字符串Person。你想通过这个字符串创建一个对象并调用它里面一个叫SayHello的方法。这时候你就必须用反射。简而言之反射就是在程序【运行时】动态地查看、创建和调用对象的能力。二反射核心“四剑客”System.Reflection命名空间下的这四个核心类类名它是干啥的Type灵魂核心。代表一个类的“蓝图”记录了类的所有信息。PropertyInfo代表类里的属性有 get/set 的那种。MethodInfo代表类里的方法。FieldInfo代表类里的字段私有变量或公有变量。2.1获取构造函数using System; using System.Reflection; public class Program { public static void Main() { // 第一步获取 Person 类的 Type 对象 Type personType typeof(Person); // 第二步获取所有公开的构造函数 ConstructorInfo[] constructors personType.GetConstructors(); Console.WriteLine($找到 {constructors.Length} 个公开的构造函数); foreach (var ctor in constructors) { // 获取构造函数的参数信息 ParameterInfo[] parameters ctor.GetParameters(); Console.WriteLine($- 构造函数名: {ctor.Name}, 参数个数: {parameters.Length}); } } }对象 / 方法作用ctorConstructorInfo 类型。它代表了某一个具体的构造函数比如public Person(int id, string name)。GetParameters()ConstructorInfo 类的方法。作用读取该构造函数的元数据返回一个ParameterInfo数组。ParameterInfo[]参数信息数组。每一个元素对应构造函数中的一个参数里面存着参数的名称、类型、是否有默认值等详细属性。2.2获取无参构造using System; using System.Reflection; Type personType typeof(Person); // 传入空数组代表寻找参数列表为空的构造函数 ConstructorInfo defaultCtor personType.GetConstructor(Type.EmptyTypes); if (defaultCtor ! null) { Console.WriteLine(成功获取到无参构造函数); // 动态执行构造函数相当于执行了 new Person() object personInstance defaultCtor.Invoke(null); Console.WriteLine($对象已创建{personInstance}); }2.3获取有参构造using System; using System.Reflection; Type personType typeof(Person); // 1. 定义参数类型数组顺序必须匹配string, int, int Type[] paramTypes new Type[] { typeof(string), typeof(int), typeof(int) }; // 2. 获取特定的构造函数 ConstructorInfo ctor personType.GetConstructor(paramTypes); if (ctor ! null) { Console.WriteLine(找到了匹配的有参构造函数); // 3. 使用 Invoke 传入具体的参数值来创建对象 object[] parameters new object[] { 小明, 20, 1 }; object personInstance ctor.Invoke(parameters); // 验证结果 Person p (Person)personInstance; Console.WriteLine($实例化成功姓名{p.Name}, 年龄{p.Age}, ID{p.Id}); } else { Console.WriteLine(未找到匹配的构造函数请检查参数类型和顺序。); }三反射的基本操作1.获取Type对象拿到类的说明书// 方式 A通过类名直接拿如果你在写代码时就知道类名 Type t1 typeof(Person); // 方式 B通过对象拿如果你手里已经有个实例了 Person p new Person(); Type t2 p.GetType(); // 方式 C通过字符串拿最强大用于插件化开发或配置文件 Type t3 Type.GetType(MyNamespace.Person);2.动态创建对象2.1语法以前你用new现在你用“魔法”object obj Activator.CreateInstance(t1); // 相当于 new Person()2.2实例using System; // 定义一个普通的类 class Person { public string Name { get; set; } // 构造函数 public Person() { Console.WriteLine(Person 被构造出来了); } } class Program { static void Main() { // 1. 获取 Person 的“类型信息” (这就是 t1) Type type typeof(Person); // 2. 动态创建对象 - 等价于 new Person() // 这里虽然没写 Person但运行时会造出 Person 的实例 object obj Activator.CreateInstance(type); // 3. 由于是 object 类型需要强转才能使用特有属性 Person p obj as Person; if (p ! null) { p.Name 云飞; Console.WriteLine(我动态创建的人叫 p.Name); } } }2.3提示因为动态创建时编译器不知道你造的是啥类型所以统一先装进object所有类的老祖宗里。你后面需要强转回原来的类型比如Person才能用。3.操作属性3.1语法哪怕属性是私有的反射也能强行“潜入”PropertyInfo prop t1.GetProperty(Name); // 给 obj 对象的 Name 属性赋值为 Gemini prop.SetValue(obj, Gemini); // 获取值 string val (string)prop.GetValue(obj);3.2实例using System; using System.Reflection; // 反射必须引用这个命名空间 // 定义一个 Person 类 class Person { // 公开属性 Name public string Name { get; set; } // 私有属性 Age正常代码里外面访问不到 private int Age { get; set; } // 打印信息的方法 public void PrintInfo() { Console.WriteLine($姓名{Name}年龄{Age}); } } class Program { static void Main() { // 1. 获取 Person 类的类型信息t1 Type personType typeof(Person); // 2. 动态创建 Person 对象obj等价于 new Person() object obj Activator.CreateInstance(personType); // 操作公开属性 Name // 3. 拿到 Name 属性的 PropertyInfo万能钥匙 PropertyInfo nameProp personType.GetProperty(Name); // 4. 给 Name 属性赋值等价于 obj.Name Gemini nameProp.SetValue(obj, Gemini); // 5. 从 Name 属性取值等价于 string val obj.Name string nameVal (string)nameProp.GetValue(obj); Console.WriteLine($动态读取 Name{nameVal}); // 【重点】操作私有属性 Age正常代码访问不到 // 注意私有属性需要加 BindingFlags 才能拿到 PropertyInfo ageProp personType.GetProperty(Age, BindingFlags.Instance | BindingFlags.NonPublic); // 给私有 Age 属性赋值正常代码里 obj.Age 是访问不到的 ageProp.SetValue(obj, 25); // 读取私有 Age 属性的值 int ageVal (int)ageProp.GetValue(obj); Console.WriteLine($强行读取私有 Age{ageVal}); // 验证赋值是否成功 ((Person)obj).PrintInfo(); } }3.3说明4.调用方法4.1语法MethodInfo method t1.GetMethod(SayHello); // 参数1哪个对象调 参数2方法需要的参数没有就传 null method.Invoke(obj, null);4.2实例using System; using System.Reflection; // 反射必须引用这个命名空间 // 定义一个 Person 类 class Person { // 公开方法SayHello无参数 public void SayHello() { Console.WriteLine(Hello! 我是Person对象); } // 带参数的公开方法SayHelloTo public void SayHelloTo(string name, int age) { Console.WriteLine($你好{name}我今年{age}岁了); } // 私有方法PrivateSayHi正常代码里外面调用不到 private void PrivateSayHi() { Console.WriteLine(我是私有方法正常代码调用不了反射能强行调用); } } class Program { static void Main() { // 1. 获取 Person 类的类型信息t1 Type personType typeof(Person); // 2. 动态创建 Person 对象obj等价于 new Person() object obj Activator.CreateInstance(personType); // 1. 调用无参数公开方法 SayHello // 3. 拿到 SayHello 方法的 MethodInfo万能遥控器 MethodInfo sayHelloMethod personType.GetMethod(SayHello); // 4. 调用方法等价于 obj.SayHello() sayHelloMethod.Invoke(obj, null); // 无参数传null // 2. 调用带参数的公开方法 SayHelloTo MethodInfo sayHelloToMethod personType.GetMethod(SayHelloTo); // 带参数第二个参数传 object[] 数组把参数放进去 sayHelloToMethod.Invoke(obj, new object[] { 云飞, 24 }); // 【重点】调用私有方法 PrivateSayHi正常代码调用不了 // 注意私有方法需要加 BindingFlags 才能拿到 MethodInfo privateMethod personType.GetMethod(PrivateSayHi, BindingFlags.Instance | BindingFlags.NonPublic); // 强行调用私有方法 privateMethod.Invoke(obj, null); } }4.3说明四反射能干什么 “骚操作”1.查看类的所有成员foreach (var item in t1.GetMembers()) { Console.WriteLine(${item.MemberType} : {item.Name}); }2.访问私有成员2.1语法这是反射最被诟病但也最强大的地方。通过BindingFlags你可以强行访问private变量FieldInfo privateField t1.GetField(_age, BindingFlags.NonPublic | BindingFlags.Instance); privateField.SetValue(obj, 18); // 强行改年龄2.2说明GetField(_age)从类的类型信息里根据名字_age去获取这个字段。BindingFlags.NonPublic | BindingFlags.Instance这是关键参数NonPublic非公开的意思是我要找private或internal的。Instance实例成员意思是找属于对象的变量而不是静态的。总结这句代码就是在说“嘿反射工具给我把那个私有的、属于对象的_age字段拿出来”五反射的优缺点1.优点极度灵活可以在不修改代码的前提下通过配置文件加载不同的逻辑这就是IOC 容器、ORM 框架的底层逻辑。解耦调用方不需要知道实现类的具体类型2.缺点性能损耗反射是动态寻找元数据比直接调用慢的多在高性能循环里不要使用代码安全性反射可以无视访问修饰符可能会破坏结构内部的封装性维护困难报错通常在运行时才发现编辑器帮不了你自己找错误

相关文章:

C#进阶知识 反射

前言 反射可以看透程序的内部构造 一什么是反射 在 C# 中,代码在被编译后会生成一堆“元数据”(Metadata)。这些元数据记录了这个类叫什么、有哪些属性、有哪些私有方法。 常规操作:你知道一个类叫 Person,所以你写…...

结合自适应锚框机制的YOLOv5优化方法:从原理到实践全解析

摘要 YOLOv5作为目标检测领域的经典算法,其默认的锚框机制在处理多样化数据集时存在局限性。本文提出一种结合自适应锚框机制的YOLOv5优化方法,通过K-means++聚类算法动态计算最优锚框尺寸,并引入锚框质量评估与动态调整策略,显著提升模型在不同尺度目标上的检测精度。实验…...

引入注意力机制的YOLOv5小目标检测方法

1. 引言 小目标检测是计算机视觉领域中的一个极具挑战性的问题。在诸如无人机航拍、卫星图像分析、自动驾驶、视频监控等应用场景中,小目标(通常定义为像素面积小于3232的目标)普遍存在。由于小目标在图像中占据的像素区域极小,特征信息匮乏,传统的目标检测算法往往难以取…...

信号完整性扫盲:你的USB3.0干扰大?可能是差分信号‘跑偏’成了共模信号

USB3.0信号干扰排查指南:当差分信号"走散"时如何力挽狂澜 去年调试一款工业摄像头时,每当隔壁车间的变频器启动,我们的USB3.0视频流就会突然卡顿。用频谱仪捕捉到的噪声波形显示,原本应该相互抵消的差分信号&#xff0c…...

Gilisoft Total Repair(全能修复大师)

链接:https://pan.quark.cn/s/a8e8b547d1f9Gilisoft Total Repair是一款功能强大的文件修复软件,中文又被成为“全能修复大师”,具有一键式智能修复引擎,可以自动解决500多个常见问题,如系统延迟、游戏崩溃和文件损坏。…...

c#如何使用ModbusRTU_c#ModbusRTU快速上手实战教程

串口参数不匹配是90%“读不到数据”的主因,需严格同步波特率、数据位、停止位、校验位;Modbus地址需换算(如40001→0);务必使用SerialPortStream替代SerialPort;CRC不可重复计算,且响应后须手动…...

5分钟掌握全能歌词神器:跨平台智能歌词提取终极解决方案

5分钟掌握全能歌词神器:跨平台智能歌词提取终极解决方案 【免费下载链接】163MusicLyrics 云音乐歌词获取处理工具【网易云、QQ音乐】 项目地址: https://gitcode.com/GitHub_Trending/16/163MusicLyrics 你是否曾为寻找一首歌的准确歌词而烦恼?&…...

【YOLOv8 改进涨点 】RT-DETR架构-通道自适应缩放机制优化主干网络结构

一、引言 本文提出了一项针对轻量级目标检测网络的改进方案——通过引入通道自适应缩放机制优化主干网络结构。该机制源自RT-DETR架构中曾使用的特征提取策略,经过二次创新后适配到YOLOv8框架。 当我们将重新设计的PulseNetV2(脉动网络V2)集成至YOLOv8n作为特征提取主干时…...

AI大模型如何重塑金融行业?智能客服、知识库、营销助手…看这篇就够了!

当前,AI大模型正深刻重塑金融行业。在业务场景中,其价值已从技术探索走向规模化落地。智能投顾领域,大模型通过分析海量市场数据与用户画像,生成个性化资产配置方案,服务效率提升超50%;信贷风控环节&#x…...

ICT+FCT一体化测试系统在汽车电子量产中的高效应用

1. ICTFCT一体化测试系统在汽车电子量产中的核心价值 汽车电子产品的量产阶段,质量控制是重中之重。传统测试方式往往需要多个独立环节,比如ICT(In-Circuit Test)和FCT(Functional Circuit Test)分开进行&a…...

从手动压枪到智能补偿:罗技鼠标宏如何革新绝地求生射击体验

从手动压枪到智能补偿:罗技鼠标宏如何革新绝地求生射击体验 【免费下载链接】logitech-pubg PUBG no recoil script for Logitech gaming mouse / 绝地求生 罗技 鼠标宏 项目地址: https://gitcode.com/gh_mirrors/lo/logitech-pubg 在《绝地求生》这类战术竞…...

基于 Java 和高德开放平台的 WebAPI 集成实践 —— 以搜索 POI2.0 为例

当今地理信息系统(GIS)的应用越来越广泛,从地图导航到商业选址,从物流配送优化到城市规划,地理数据的处理和分析成为了许多应用的核心需求。而 POI(Point of Interest,兴趣点)数据作…...

nlp_gte_sentence-embedding_chinese-large一文详解:中文分词对向量质量的影响

nlp_gte_sentence-embedding_chinese-large一文详解:中文分词对向量质量的影响 你有没有遇到过这种情况?用同一个文本向量模型处理两段意思差不多的中文,算出来的相似度却很低。或者,明明是两个不同的词,模型却认为它…...

LaTeX公式转换Word终极方案:3步实现高效学术写作

LaTeX公式转换Word终极方案:3步实现高效学术写作 【免费下载链接】LaTeX2Word-Equation Copy LaTeX Equations as Word Equations, a Chrome Extension 项目地址: https://gitcode.com/gh_mirrors/la/LaTeX2Word-Equation LaTeX2Word-Equation是一款专为学术…...

Everything 1.5史诗级升级了:不止搜文件名,可以搜文件内容了

今早翻旧文档,记不清“2026预算表”的文件名。用Everything 1.5的全文搜索,输关键词秒出结果。突然觉得,好工具像记忆的“放大镜”,模糊的事儿也能拎清。 咱就是说,搜文件不该费劲儿。 Everything 搜文件名快。 …...

快速上手Gemma-3-12B-IT聊天助手:WebUI部署与使用技巧

快速上手Gemma-3-12B-IT聊天助手:WebUI部署与使用技巧 1. 项目简介 1.1 什么是Gemma-3-12B-IT? Gemma-3-12B-IT是Google最新推出的开源大语言模型,属于Gemma系列的第三代产品。这个版本特别针对对话场景进行了优化: 12B参数&a…...

加深理解神经元的工作原理:感知机预测的实现

怎么去理解一个神经元的工作原理? 加权求和,激活函数. 这些概念反反复复的就是记不住,怎么理解监督学习,权重更新规则,这些理论模模糊糊总是理解不到. 下面用一个简单的例子.加深上面这些内容的理解 使用Python和NumPy(不使用深度学习框架),实现一个感知机,用于对一…...

Flowise效果展示:不同Embedding模型(BGE/bge-m3)在中文场景表现

Flowise效果展示:不同Embedding模型(BGE/bge-m3)在中文场景表现 1. 引言:当可视化拖拽遇到中文Embedding 想象一下这样的场景:你手里有一堆中文文档,想要快速搭建一个智能问答系统,但又不愿意…...

【工具推荐】EVCapture 电脑录屏软件,无水印超省心

【工具推荐】EVCapture - 免费好用的电脑录屏软件 一、工具简介 EVCapture 是一款免费无水印的电脑屏幕录制软件,支持Windows系统。它可以录制电脑屏幕、摄像头、声音,是一款实用的录屏工具。 官方信息项目信息软件名称EVCapture版本v5.4.5类型屏幕录制软…...

用Python模拟Barra CNE5风险模型:手把手教你构建A股量化策略(附完整代码)

用Python构建A股多因子风险模型:从理论到实战的完整指南 在量化投资领域,风险模型是构建稳健策略的核心基础设施。对于A股市场而言,由于交易机制、投资者结构和政策环境的特殊性,直接套用海外成熟市场的风险模型往往效果不佳。本文…...

My first article

12345...

重新理解基础数据结构(动态数组,链表)

1 最近在准备面试,发现 ArrayList 扩容机制总是死记硬背,过段时间就忘。索性花几小时彻底啃一遍源码,争取一次拿下、终身不忘。2 ArrayList 底层是动态数组。Java 原生数组一旦定义长度就不可变,使用场景受限。ArrayList 就是对数…...

【Azure App Service】PHP页面上传文件413错误的解决方案

问题描述 在使用 Azure App Service(Linux PHP) 部署 Web 应用时,如果上传文件大于1MB,就会遇到 HTTP 413(Request Entity Too Large) 错误。 错误截图 问题解答 一、HTTP 413 错误的本质含义 413 Req…...

如何备份备库Data Guard_在Standby端执行RMAN备份减轻主库压力

不能直接在备库连RMAN TARGET /备份,因DG备库控制文件为只读的standby控制文件,RMAN默认不信任其作为备份源,需先配置DB_UNIQUE_NAME、挂载standby控制文件并编目数据文件。为什么不能直接在备库连 RMAN TARGET / 就开干因为默认情况下&#…...

VideoSrt:终极视频字幕自动生成解决方案,让字幕制作变得简单快速

VideoSrt:终极视频字幕自动生成解决方案,让字幕制作变得简单快速 【免费下载链接】video-srt-windows 这是一个可以识别视频语音自动生成字幕SRT文件的开源 Windows-GUI 软件工具。 项目地址: https://gitcode.com/gh_mirrors/vi/video-srt-windows …...

私有化AI视频助手搭建实录:当Ollama遇上OpenClaw

AI视频生成的热度仍在攀升,从HappyHorse-1.0匿名屠榜到各家模型竞相开源,创作者似乎迎来了最好的时代。但一个现实问题始终悬而未决:云端服务固然方便,可谁愿意把未公开的脚本、商业素材甚至客户数据,毫无保留地交给一…...

深入解析AMD Ryzen处理器硬件调试:5大核心功能实战指南

深入解析AMD Ryzen处理器硬件调试:5大核心功能实战指南 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://g…...

Spring Boot @Value 绑定 Set 失败?

Spring Boot Value 绑定 Set 失败&#xff1f;一、问题背景在同事项目开发过程中&#xff0c;遇到了一个看起来很简单但实际很容易踩坑的问题&#xff1a;同事希望在 application.properties 中配置一个字符串集合&#xff0c;然后在代码中直接注入为 Set<String>。配置如…...

【含最新安装包】5 分钟完成 OpenClaw 2.6.2 Windows 部署

Windows 一键部署 OpenClaw 教程&#xff5c;5 分钟搞定本地 AI 智能体&#xff0c;告别复杂配置 核心亮点&#xff1a;零代码门槛&#xff5c;全程可视化&#xff5c;无需手动配环境&#xff5c;内置所有依赖&#xff5c;28 万 Tokens 额度 下载地址&#xff1a;【点击下载o…...

AI生成内容版权:法律与职业风险

——软件测试从业者的专业视角与风险防控一、AI版权争议的法律核心&#xff1a;独创性认定《著作权法》第三条明确规定&#xff0c;作品需满足独创性智力成果双重要件。近年司法实践通过典型案例确立以下原则&#xff1a;关键司法判例解析案例案号核心结论对测试工作的启示AI图…...