C#中的反射(Reflection)使用经典案例

文章目录

      • 1. 动态加载和调用类的方法
      • 2. 记录用户修改行为
      • 3. 调用私有构造函数
      • 4. 泛型类型的动态创建和使用
      • 5. 动态类型转换与检查
      • 6. 获取和设置私有、受保护成员
      • 7. 枚举程序集、模块、类型等信息
      • 8. 处理泛型类型参数
      • 9. 动态生成代码或动态编译
      • 10. 配置驱动的应用程序扩展
      • 注意事项:

C#中的反射(Reflection)是.NET框架提供的一种强大的运行时元编程机制,它允许程序在运行时获取类型信息、创建对象实例、调用方法、访问字段和属性等,而这些操作在编译时可能是未知的。以下是几个使用反射的典型场景:

1. 动态加载和调用类的方法

假设有一个库包含多个实现了同一接口的类,用户可以通过配置文件指定要使用的具体类名和方法名。通过反射,可以在运行时根据配置加载相应的类型,并调用指定的方法。

// 假设有个接口和其实现类
public interface ICalculator
{
    int Calculate(int a, int b);
}

public class Adder : ICalculator
{
    public int Calculate(int a, int b) => a + b;
}

// 配置中读取类名
string className = "Adder";
Type calculatorType = Type.GetType(className);

// 创建实例并调用方法
ICalculator calculator = (ICalculator)Activator.CreateInstance(calculatorType);
int result = calculator.Calculate(3, 5);

2. 记录用户修改行为

如您提到的应用场景,系统需要记录用户修改了哪个实体类的哪些字段。通过反射,可以遍历实体类的所有属性,在用户修改后记录下变化的属性名和新旧值。

public class User
{
    public string Name { get; set; }
    public int Age { get; set; }
    // 其他属性...
}

// 用户更新了一个User实例
var user = new User { Name = "OldName", Age = 30 };

foreach (var property in properties)
{
    // 获取旧值(假设这是更改前的值)
    var oldValue = property.GetValue(user);

    // 模拟用户更改属性值
    if (property.Name == "Name")
    {
        user.Name = "NewName";
    }

    // 再次获取新值
    var currentValue = property.GetValue(user);

    // 如果旧值与当前值不相等,则记录变更
    if (!object.Equals(oldValue, currentValue) && property.CanRead && property.CanWrite)
    {
        LogChange(property.Name, oldValue, currentValue);
    }
}

3. 调用私有构造函数

反射还可以用来调用非公开的构造函数,比如破坏单例模式时可能会用到:

public sealed class Singleton
{
    private static readonly Singleton instance = new Singleton();

    private Singleton() { }

    public static Singleton Instance => instance;

    // 通过反射破坏单例模式
    public static Singleton CreateAnotherInstance()
    {
        ConstructorInfo ctor = typeof(Singleton).GetConstructor(
            BindingFlags.Instance | BindingFlags.NonPublic,
            null, Type.EmptyTypes, null);
        return (Singleton)ctor.Invoke(null);
    }
}

4. 泛型类型的动态创建和使用

反射结合泛型,可以实现在不知道具体类型参数的情况下动态创建泛型类型实例:

public class GenericClass<T>
{
    public T Value { get; set; }
}

Type genericType = typeof(GenericClass<>).MakeGenericType(typeof(string));
dynamic instance = Activator.CreateInstance(genericType);
instance.Value = "Hello, World!";

C#反射除了上述提到的几个典型应用场景外,还有以下一些常见的用途:

5. 动态类型转换与检查

  • 判断一个对象是否实现了某个接口或继承自某个类。
  • 在不知道具体类型的情况下,将对象动态转换为指定类型。
object obj = new MyDerivedClass();
Type type = obj.GetType();

// 检查类型是否实现了某个接口
bool isDisposable = typeof(IDisposable).IsAssignableFrom(type);

// 动态转换
if (type == typeof(MyDerivedClass))
{
    MyDerivedClass derivedObj = (MyDerivedClass)obj;
    // 使用转换后的对象...
}

6. 获取和设置私有、受保护成员

  • 反射可以访问私有字段、属性和方法,这在测试框架中特别有用,可以模拟对私有成员的调用或者验证其值。
public class MyClass
{
    private int myPrivateField;
    
    public void SetPrivateValue(int value)
    {
        this.myPrivateField = value;
    }
}

var instance = new MyClass();
FieldInfo field = typeof(MyClass).GetField("myPrivateField", BindingFlags.NonPublic | BindingFlags.Instance);
field.SetValue(instance, 42);  // 设置私有字段值

int fieldValue = (int)field.GetValue(instance);  // 获取私有字段值

7. 枚举程序集、模块、类型等信息

  • 在大型应用程序中,可能需要枚举整个程序集中所有类型的元数据信息,比如获取所有的类名、特性(Attributes)等。
Assembly assembly = Assembly.GetExecutingAssembly();
foreach (Type type in assembly.GetTypes())
{
    Console.WriteLine($"Type: {type.FullName}");

    foreach (Attribute attribute in Attribute.GetCustomAttributes(type))
    {
        Console.WriteLine($"  Attribute: {attribute.GetType().Name}");
    }
}

8. 处理泛型类型参数

  • 反射可以帮助获取泛型类型的具体参数类型,并据此创建特定类型的实例。

9. 动态生成代码或动态编译

  • .NET Framework 和 .NET Core 提供了 System.Reflection.Emit 命名空间,允许开发者在运行时动态生成类型和方法。这对于实现AOP(面向切面编程)、动态代理或其他高级编程技术非常有用。

10. 配置驱动的应用程序扩展

  • 反射常用于构建插件式架构,根据配置文件加载不同插件(DLL)并在运行时动态加载并执行插件中的代码。

总之,C#反射是一个强大的工具,它允许程序在运行时获得关于类型和程序集的信息,并基于这些信息进行操作,极大地增强了应用程序的灵活性和适应性。但需要注意的是,过度使用反射可能会降低性能,应谨慎权衡其带来的便利性和潜在的成本。

注意事项:

  • 反射通常会带来性能开销,因为它涉及到运行时类型查找和动态方法调用。
  • 安全性方面,过度依赖反射可能导致代码容易受到攻击,例如绕过私有成员保护机制。
  • 静态编译优化对反射调用可能不适用,因此在对性能敏感的场合应谨慎使用反射。

python推荐学习汇总连接:
50个开发必备的Python经典脚本(1-10)

50个开发必备的Python经典脚本(11-20)

50个开发必备的Python经典脚本(21-30)

50个开发必备的Python经典脚本(31-40)

50个开发必备的Python经典脚本(41-50)
————————————————

​最后我们放松一下眼睛
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/319187.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CBA业务架构师认证考试含金量

CBA业务架构师认证考试的含金量主要体现在以下几个方面&#x1f447; 1️⃣权威性 &#x1f48e;CBA业务架构师是业务架构师协会提供了一项国际认证计划&#xff0c;该计划可以衡量业务架构师的能力&#xff0c; 并向证明公认的熟练程度的个人授予认证业务架构师(Certified Bus…

第四节课 XTuner 大模型单卡低成本微调实战 作业

文章目录 笔记作业 笔记 XTuner 大模型单卡低成本微调原理&#xff1a;https://blog.csdn.net/m0_49289284/article/details/135532140XTuner 大模型单卡低成本微调实战&#xff1a;https://blog.csdn.net/m0_49289284/article/details/135534817 作业 基础作业&#xff1a;…

限时福利,Adobe InCopy2024下载安装指南

Adobe InCopy 下载链接 https://pan.baidu.com/s/16j5MiXqfGw6puQbgyQnJSQ?pwd0531 #2024版本 1.鼠标右击【InCopy2024(64bit)】压缩包&#xff08;win11及以上系统需先点击“显示更多选项”&#xff09;【解压到 InCopy2024(64bit)】。 2.打开解压后的文件夹&#xff0c;鼠…

codeforces(C++ Summation Game)

题目&#xff1a; 翻译&#xff1a; 思路&#xff1a; 1、将数据从大到小排序 2、用前缀和 3、每次用总和减去2倍的乘-1的数&#xff0c;求最大值 代码&#xff1a; #include <iostream> #include<algorithm> using namespace std;void solve() {int n, k, x;ci…

Baumer工业相机堡盟工业相机如何使用OpenCV实现相机图像的显示(C++)

Baumer工业相机堡盟工业相机如何使用OpenCV实现相机图像的显示&#xff08;C&#xff09; Baumer工业相机Baumer工业相机的图像转换为OpenCV的Mat图像的技术背景在NEOAPI SDK里使用OpenCV实现相机图像的显示联合OpenCV实现相机图像的显示测试演示图 工业相机通过使用OpenCV实现…

Docker介绍安装及使用

目录 引言一、什么是Docker?二、Docker的优势三、Docker的架构四、Docker的安装五、Docker的基本使用六、Docker与传统虚拟化的比较七、Docker的应用场景八、总结 引言 在现代的软件开发和部署中&#xff0c;容器化技术已经成为了一种趋势。Docker作为容器化技术的领先者&…

Centos7 系统使用Playbook批量部署多台LNMP环境

使用Playbook批量部署多台LNMP环境 配置absible源 wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo yum -y install ansible 配置主机清单 定义…

常见的加密算法

加密算法 AES 高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的)。对称加密算法也就是加密和解密用相同的密钥&#xff0c;具体的加密流程如下图&#xff1a; RSA RSA 加密算法是一种典型的非对称加密算法&am…

山西电力市场日前价格预测【2024-01-15】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2024-01-15&#xff09;山西电力市场全天平均日前电价为399.10元/MWh。其中&#xff0c;最高日前电价为583.33元/MWh&#xff0c;预计出现在18:15。最低日前电价为275.09元/MWh&#xff0c;预计…

第 3 场 蓝桥杯小白入门赛 解题报告 | 珂学家 | 单调队列优化的DP + 三指针滑窗

前言 整体评价 T5, T6有点意思&#xff0c;这场小白入门场&#xff0c;好像没真正意义上的签到&#xff0c;整体感觉是这样。 A. 召唤神坤 思路: 前后缀拆解 #include <iostream> #include <algorithm> #include <vector> using namespace std;int main()…

二分图最大匹配——匈牙利算法详解

文章目录 零、前言一、红娘牵线二、二分图最大匹配2.1概念2.2交替路2.3增广路2.4匈牙利算法2.4.1算法原理2.4.2算法示例2.4.3代码实现 3.OJ练习3.1模板3.2棋盘覆盖3.3車的放置 零、前言 关于二分图的基本知识见&#xff1a;二分图及染色法判定 一、红娘牵线 一位红娘近日遇到一…

Word插件-大珩助手-手写电子签名

手写签名 支持鼠标写&#xff0c;支持触摸屏写&#xff0c;点击画笔按钮切换橡皮擦&#xff0c;支持清空画板重写&#xff0c;点击在word中插入签名&#xff0c;可插入背景透明的签字图 素材库-保存签名 将写好的签字图复制粘贴到素材库中&#xff0c;以便永久使用&#xff…

详解Java之Spring框架中事务管理的艺术

第1章&#xff1a;引言 大家好&#xff0c;我是小黑&#xff0c;咱们今天聊聊Spring框架中的事务管理。不管是开发小型应用还是大型企业级应用&#xff0c;事务管理都是个不可避免的话题。那么&#xff0c;为什么事务管理这么重要呢&#xff1f;假设在银行系统中转账时&#x…

OpenCV——多分辨率LBP的计算方法

目录 一、算法原理1、原理概述2、参考文献 二、代码实现三、结果展示 OpenCV——多分辨率LBP的计算方法由CSDN点云侠原创&#xff0c;爬虫自重。如果你不是在点云侠的博客中看到该文章&#xff0c;那么此处便是不要脸的爬虫。 一、算法原理 1、原理概述 基本LBP算子虽然在早期…

Qt/QML编程学习之心得:使用camera摄像头(35)

汽车应用中,camera起到了越来越多的作用,数字化的作用,这点无可争议,而作为GUI设计工具,如何让Camera类的应用能更好的发挥作用呢? You can use Camera to capture images and movies from a camera, and manipulate the capture and processing settings that get appl…

关于 setData 同步异步的问题

小程序官方文档中的回答解释: 所以大概意思就是: 1.setData在逻辑层的操作是同步&#xff0c;因此this.data中的相关数据会立即更新,比如下面的例子: const a 1 this.setData({b: a ? a : , }) console.log(that.data.b) // 1 2. setData在视图层的操作是异步&#xff0c;…

Linux Ubuntu搭建我的世界Minecraft服务器实现好友远程联机MC游戏

文章目录 前言1. 安装JAVA2. MCSManager安装3.局域网访问MCSM4.创建我的世界服务器5.局域网联机测试6.安装cpolar内网穿透7. 配置公网访问地址8.远程联机测试9. 配置固定远程联机端口地址9.1 保留一个固定tcp地址9.2 配置固定公网TCP地址9.3 使用固定公网地址远程联机 前言 Li…

C语言之从浅入深一步一步全方位理解指针【附笔试题】

文章目录 前言从浅入深理解指针《第一阶段》一、内存和地址1.1 内存1.2 究竟该如何理解编址 二、指针变量和地址2.1 取地址操作符&#xff08;&&#xff09; 三、指针变量和解引用操作符&#xff08;*&#xff09;3.1 指针变量3.2 如何拆解指针类型3.3 解引用操作符 四、指…

web网页设计学习记录(五)

1.如何设置背景色呢&#xff1f; 格式为&#xff1a; <body bgcolor"色彩值"> “色彩值”可以为色彩的英文名或相应十六进制值。 2.如何将图片作为背景呢&#xff1f; 格式为&#xff1a;<body background"图片文件名"> 使用<body&g…

具于xilinx FPGA的可动态配置DDS频率控制字的DDS IP核使用例程详解

目录 1 概述2 IP examples功能3 IP 使用例程4注意事项5 DDS IP Examples下载位置 1 概述 本文用于讲解xilinx IP 的dds ip examples&#xff08;动态配置频率&#xff09;的功能说明&#xff0c;方便使用者快速上手。 2 IP examples功能 本examples 是月隐编写的针对DDS的使…