反射机制学习

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

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

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

2. 示例代码

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

2.1 定义类

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

csharp 复制代码
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 关键字

csharp 复制代码
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 获取类成员

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

csharp 复制代码
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 调用方法

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

csharp 复制代码
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 加载程序集

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

csharp 复制代码
// 方式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 读写属性值

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

csharp 复制代码
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#中非常强大的功能,它允许程序在运行时动态地获取类型信息并操作对象。

相关推荐
软件黑马王子3 小时前
Unity游戏制作中的C#基础(5)条件语句和循环语句知识点全解析
游戏·unity·c#
shepherd枸杞泡茶3 小时前
第3章 3.3日志 .NET Core日志 NLog使用教程
c#·asp.net·.net·.netcore
Aimeast9 小时前
关于选择最佳.NET Core SSH服务器库的全面分析
c#·ssh
蒋劲豪10 小时前
WPF项目暴露WebApi接口;WinForm项目暴露WebApi接口;C#项目暴露WebApi接口;
开发语言·c#·wpf
code bean11 小时前
【C# 数据结构】队列 FIFO
开发语言·数据结构·c#
时光追逐者13 小时前
推荐几款开源免费的 .NET MAUI 组件库
microsoft·开源·c#·.net·.net core·maui
软件黑马王子15 小时前
C#初级教程(1)——C# 与.NET 框架:探索微软平台编程的强大组合
开发语言·c#
shepherd枸杞泡茶15 小时前
第3章 3.2 配置系统 .NET Core配置系统
后端·c#·asp.net·.net
编程乐趣17 小时前
一文掌握DeepSeek本地部署+Page Assist浏览器插件+C#接口调用+局域网访问!全攻略来了!
开发语言·c#
我是苏苏17 小时前
C#基础:使用Linq进行简单去重处理(DinstinctBy/反射)
开发语言·c#·linq