反射机制学习

embedded/2025/1/3 14:31:46/

C# 反射机制详解:动态创建对象、访问成员与加载程序集

在C#中,反射(Reflection)是一种强大的机制,它允许程序在运行时动态地获取类型信息、创建对象、访问成员以及调用方法。本文将基于一个示例代码,详细讲解如何使用反射实现这些功能,并优化代码结构,使其更清晰易读。
1. 反射的基本概念

反射是.NET框架提供的一种机制,它允许程序在运行时动态地获取类型信息(如类、方法、属性等),并可以动态地创建对象、调用方法或访问字段。反射的核心类是 System.Type,它表示类型的元数据。

2. 示例代码

以下是一个完整的示例代码,展示了如何使用反射动态创建对象、访问成员以及加载程序集。

2.1 定义类

首先,我们定义了两个类:UserInfoManuInfo

public class UserInfo
{private int _id;public string UserId { get; set; }public string UserName { get; set; }public string Email { get; set; }public int Age;// 构造方法public UserInfo() { }public UserInfo(int id, string name){this.UserId = id.ToString();this.UserName = name;}public void Show(){Console.WriteLine("Hello. This is a test.");}public void Show(string name){Console.WriteLine($"Show {name}");}public int GetAge(){return Age;}public static void ShowInfo(){Console.WriteLine(" static ShowInfo ");}
}public class ManuInfo
{public int ManuId { get; set; }public string ManuName { get; set; }public string FrmName { get; set; }public string Remark { get; set; }
}
2.2 使用反射动态创建对象

通过反射,我们可以动态创建对象,而不需要直接使用 new 关键字

Type type = typeof(UserInfo);
UserInfo user2 = Activator.CreateInstance<UserInfo>();
UserInfo user3 = (UserInfo)Activator.CreateInstance(typeof(UserInfo));
object user4 = Activator.CreateInstance(typeof(UserInfo));user2.UserName = "李四";
user2.Email = string.Empty;
user2.UserId = "12345";user3.UserName = "张三";
user3.Email = "123456@163.com";
user3.UserId = "1224sss";
2.3 获取类成员

通过反射,我们可以获取类的属性、字段和方法。

var prop = type.GetProperties(); // 获取所有公共属性
PropertyInfo propInfo = type.GetProperty("UserName"); // 获取指定属性
var fields = type.GetFields(); // 获取所有字段
var priFields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic); // 获取私有字段
var pubMethods = type.GetMethods(); // 获取所有公共方法
2.4 调用方法

通过反射,我们可以动态调用方法,包括静态方法和实例方法。

MethodInfo methodInfo1 = type.GetMethod("Show", new Type[] { }); // 无参调用
methodInfo1.Invoke(user4, null);MethodInfo methodInfo2 = type.GetMethod("Show", new Type[] { typeof(string) }); // 有参调用
methodInfo2.Invoke(user4, new object[] { "王明" });MethodInfo methodInfo3 = type.GetMethod("ShowInfo", new Type[] { }); // 静态方法调用
methodInfo3.Invoke(null, null);
2.5 加载程序集

通过反射,我们可以动态加载程序集,并创建其中的对象。


// 方式1:Load()
Assembly ass1 = Assembly.Load("ModelsLib");
Type typeMenu1 = ass1.GetType("ModelsLib.ManuInfo");
object manuInfo1 = Activator.CreateInstance(typeMenu1);// 方式2:LoadFile()
Assembly ass2 = Assembly.LoadFile(@"C:\path\to\ModelsLib.dll");
Type typeMenu2 = ass2.GetType("ModelsLib.ManuInfo");
object manuInfo2 = Activator.CreateInstance(typeMenu2);// 方式3:LoadFrom()
Assembly ass3 = Assembly.LoadFrom("ModelsLib.dll");
Type typeMenu3 = ass3.GetType("ModelsLib.ManuInfo");
object manuInfo3 = Activator.CreateInstance(typeMenu3);
2.6 读写属性值

通过反射,我们可以动态地读取和写入对象的属性值。


typeMenu1.GetProperty("ManuId").SetValue(manuInfo1, 5);
typeMenu1.GetProperty("ManuName").SetValue(manuInfo1, "王华");foreach (PropertyInfo property in typeMenu1.GetProperties())
{object objValue = property.GetValue(manuInfo1);Console.WriteLine(objValue.ToString());
}
3. 反射的优缺点
3.1 优点

动态性:反射允许程序在运行时动态地获取类型信息并操作对象,适用于需要高度灵活性的场景。
扩展性:通过反射,可以加载外部程序集并调用其中的类型和方法,实现插件化架构。
通用性:反射可以用于编写通用代码,例如序列化、反序列化、ORM框架等。

3.2 缺点

性能开销:反射操作比直接调用代码慢,因为需要在运行时解析类型信息。
安全性:反射可以访问私有成员,可能破坏封装性,带来安全隐患。
复杂性:反射代码通常比直接调用代码更复杂,难以调试和维护。

4. 总结

反射是C#中非常强大的功能,它允许程序在运行时动态地获取类型信息并操作对象。


http://www.ppmy.cn/embedded/150356.html

相关文章

3.5mm耳机接口硬件连接

结构 以最复杂的结构为例 简单的结构无非就是没有MIC&#xff08;麦克风&#xff09;接口 上图的5就是Detect的作用 上面这两款产品都为3.5mm的音频插座&#xff0c;图一 为连接4节的音频座&#xff0c;而且有两个开关&#xff0c;1接地&#xff0c;2接MIC&#xff0c;3接左声…

VSCode快捷键Ctrl+/是注释;Ctrl+\是拆分编辑器;Ctrl+w是关闭编辑器

VSCode快捷键Ctrl/是注释&#xff1b;Ctrl\是拆分编辑器&#xff1b;Ctrlw是关闭编辑器 Ctrl/是注释&#xff0c;但是如果没弄对&#xff0c;有可能会按成Ctrl\ ,而这个快捷键是拆分编辑器&#xff0c;尤其是多按几个&#xff0c;就拆分出很多窗口&#xff0c;非常影响编程工作…

MySQL的索引

索引是对数据库表中一列或多列的值进行排序的一种结构。MySQL索引的建立对于MySQL的高效运行是很重要的&#xff0c;索引可以大大提高MySQL的检索速度。索引只是提高效率的一个因素&#xff0c;如果你的MySQL有大数据量的表&#xff0c;就需要花时间研究建立最优秀的索引&#…

STM32单片机芯片与内部45 UART 不定长度接收 标志位结束 定时器超时 串口空闲中断

目录 一、标志位结束法 1、实现原理 2、代码 3、优缺点 优点&#xff1a; 缺点&#xff1a; 总结&#xff1a; 二、串口空闲中断 1、中断读取 2、DMA接收 3、优缺点 优点&#xff1a; 缺点&#xff1a; 三、定时器空闲超时 1、实现原理 2、代码 3、优缺点 优…

WPF 绘制过顶点的圆滑曲线 (样条,贝塞尔)

在一个WPF项目中要用到样条曲线&#xff0c;必须过顶点&#xff0c;圆滑后还不能太走样&#xff0c;捣鼓一番&#xff0c;发现里面颇有玄机&#xff0c;于是把我多方抄来改造的方法发出来&#xff0c;方便新手&#xff1a; 如上图&#xff0c;看代码吧&#xff1a; ----------…

Framework开发入门(一)之源码下载

一、使用Linux操作系统的小伙伴可以跳转到官网链接按提示操作 官网源码地址&#xff1a;下载源代码 | Android Open Source Project 1.创建一个空目录来存放您的工作文件。为其指定一个您喜欢的任意名称&#xff1a; mkdir WORKING_DIRECTORYcdWORKING_DIRECTORY …

Kafka消息不丢失与重复消费问题解决方案总结

1. 生产者层面 异步发送与回调处理 异步发送方式&#xff1a;生产者一般使用异步方式发送消息&#xff0c;异步发送有消息和回调接口两个参数。在回调接口的重写方法中&#xff0c;可通过异常参数判断消息发送状态。若消息发送成功&#xff0c;异常参数为null&#xff1b;若发…

使用OpenAI、LangChain、MongoDB构建一个AI agent✨

LangChain真是好起来了。24年中的时候用LangChain V2差点把我气死&#xff0c;现在V3用起来开始真香了~ 像 ChatGPT、Gemini 和 Claude 这样的大模型已成为企业必不可少的工具。如今&#xff0c;几乎每家公司都希望根据自己的需求或客户群体&#xff0c;开发一款定制化的AI Age…