c#的反射和特性

在 C# 中,反射(Reflection)和特性(Attributes)是两个强大的功能,它们在运行时提供元编程能力,广泛用于框架开发、对象映射和动态行为扩展。以下是对它们的详细介绍,包括定义、用法、示例和应用场景。


一、反射(Reflection)

什么是反射?

反射是 C# 运行时的一种机制,允许程序在运行时动态检查和操作类型、对象及其元数据(如类、方法、属性等)。通过反射,开发者可以:

  • 获取类型信息(如类名、方法名)。
  • 动态创建对象。
  • 调用方法或访问属性/字段。
  • 检查或修改私有成员(需注意权限)。

反射的核心类库位于 System.Reflection 命名空间。


反射的核心类和方法

  1. Type

    • 表示类型的元数据,是反射的核心。
    • 获取方式:
      • typeof(ClassName):静态获取类型。
      • object.GetType():从实例获取类型。
  2. Assembly

    • 表示程序集,可以加载和检查 DLL 或 EXE。
  3. MethodInfoPropertyInfoFieldInfo

    • 分别表示方法、属性和字段的元数据。
  4. Activator

    • 用于动态创建对象实例。

示例 1:基本反射操作

using System;
using System.Reflection;class Person
{public string Name { get; set; }private int age = 25;public void SayHello(){Console.WriteLine($"Hello, I'm {Name}, {age} years old.");}
}class Program
{static void Main(){// 获取类型Type type = typeof(Person);Console.WriteLine($"类名: {type.Name}");// 创建实例object instance = Activator.CreateInstance(type);// 设置属性PropertyInfo nameProp = type.GetProperty("Name");nameProp.SetValue(instance, "Alice");// 获取私有字段并修改FieldInfo ageField = type.GetField("age", BindingFlags.NonPublic | BindingFlags.Instance);ageField.SetValue(instance, 30);// 调用方法MethodInfo method = type.GetMethod("SayHello");method.Invoke(instance, null);// 输出所有公共方法Console.WriteLine("\n公共方法:");foreach (MethodInfo m in type.GetMethods(BindingFlags.Public | BindingFlags.Instance)){Console.WriteLine(m.Name);}}
}
输出
类名: Person
Hello, I'm Alice, 30 years old.公共方法:
get_Name
set_Name
SayHello
ToString
Equals
GetHashCode
GetType
说明
  • typeof:获取 Person 的类型信息。
  • Activator.CreateInstance:动态创建实例。
  • GetPropertySetValue:访问和修改属性。
  • GetField:通过 BindingFlags 获取私有字段。
  • Invoke:动态调用方法。

示例 2:加载程序集

using System;
using System.Reflection;class Program
{static void Main(){// 加载当前程序集Assembly assembly = Assembly.GetExecutingAssembly();foreach (Type type in assembly.GetTypes()){Console.WriteLine($"类型: {type.FullName}");}}
}
输出
类型: Program
说明
  • Assembly.GetExecutingAssembly:获取当前程序集。
  • GetTypes:列出程序集中所有类型。

反射的优缺点

  • 优点
    • 动态性:运行时决定行为,适合插件系统或框架。
    • 灵活性:无需提前知道类型即可操作。
  • 缺点
    • 性能开销:反射比直接调用慢。
    • 安全性:可能暴露私有成员,需谨慎使用。

二、特性(Attributes)

什么是特性?

特性是 C# 中的一种声明性标签,用于为代码元素(如类、方法、属性等)附加元数据。特性在运行时可以通过反射读取,用于控制行为或提供额外信息。

特性定义在 System 命名空间中,常用基类是 Attribute


特性的定义与使用

  1. 定义特性

    • 继承自 Attribute,添加 [AttributeUsage] 指定适用范围。
  2. 应用特性

    • 使用方括号 [ ] 标记在代码元素上。
  3. 读取特性

    • 通过反射的 GetCustomAttributes 方法获取。

示例 1:自定义特性

using System;
using System.Reflection;// 定义特性
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
public class DescriptionAttribute : Attribute
{public string Description { get; }public DescriptionAttribute(string description){Description = description;}
}// 使用特性
[Description("这是一个测试类")]
class TestClass
{[Description("这是一个测试方法")]public void TestMethod(){Console.WriteLine("Hello from TestMethod!");}
}class Program
{static void Main(){// 获取类特性Type type = typeof(TestClass);DescriptionAttribute classAttr = (DescriptionAttribute)Attribute.GetCustomAttribute(type, typeof(DescriptionAttribute));Console.WriteLine($"类描述: {classAttr?.Description}");// 获取方法特性MethodInfo method = type.GetMethod("TestMethod");DescriptionAttribute methodAttr = (DescriptionAttribute)method.GetCustomAttribute(typeof(DescriptionAttribute));Console.WriteLine($"方法描述: {methodAttr?.Description}");// 调用方法object instance = Activator.CreateInstance(type);method.Invoke(instance, null);}
}
输出
类描述: 这是一个测试类
方法描述: 这是一个测试方法
Hello from TestMethod!
说明
  • [AttributeUsage]:限制特性只能用于类和方法,且不可重复。
  • GetCustomAttribute:获取指定类型的特性实例。
  • Description:特性中存储的元数据。

示例 2:内置特性 - [Obsolete]

using System;class Program
{[Obsolete("此方法已过时,请使用 NewMethod", false)] // false 表示警告,true 表示错误static void OldMethod(){Console.WriteLine("Old Method");}static void NewMethod(){Console.WriteLine("New Method");}static void Main(){OldMethod(); // 编译器会发出警告NewMethod();}
}
输出(带警告)
Old Method
New Method
说明
  • [Obsolete]:标记方法为过时,编译时提示开发者。

特性的应用场景

  1. 框架开发

    • ASP.NET Core 使用 [Route][HttpGet] 等特性定义路由和行为。
    • Entity Framework 使用 [Table][Key] 配置数据库映射。
  2. 验证与描述

    • [Required][MaxLength] 用于数据验证。
    • [Description] 添加文档信息。
  3. 条件编译

    • [Conditional("DEBUG")] 在特定条件下执行方法。

反射与特性的结合

反射和特性经常一起使用,例如:

  • 依赖注入:通过反射扫描带有特定特性的类,动态注入。
  • 序列化:检查 [Serializable] 或自定义特性,决定序列化字段。

优缺点

  • 优点
    • 声明式编程:减少硬编码,提高可维护性。
    • 元数据丰富:为工具和框架提供信息。
  • 缺点
    • 运行时开销:读取特性需要反射。
    • 复杂度:过度使用可能使代码难以理解。

总结

  • 反射:运行时动态操作类型和对象,适合需要灵活性的场景(如插件系统)。
  • 特性:为代码添加元数据,配合反射实现声明式逻辑(如框架配置)。

通过反射,你可以动态调用方法或创建实例;通过特性,你可以为代码附加规则或描述。这两者在 C# 中是构建高级功能(如 ORM、AOP)的基石。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云终端的作用,此刻在校园和医院里具象化

数字化转型已经成为各行各业交流的热点话题,校园和医院这两个重要领域正经历着深刻变革。云终端,正以实际应用成果展现其独特作用,让人们切实感受到它带来的高效与便利。 传统的教学中,学校机房的电脑设备更新换代成本高&#xf…

UniApp快速表单组件

环境&#xff1a;vue3 uni-app 依赖库&#xff1a;uview-plus、dayjs 通过配置项快速构建 form 表单 使用 <script setup>import CustomCard from /components/custom-card.vue;import { ref } from vue;import CustomFormItem from /components/form/custom-form-it…

Android: Handler 的用法详解

Android 中 Handler 的用法详解 Handler 是 Android 中用于线程间通信的重要机制&#xff0c;主要用于在不同线程之间发送和处理消息。以下是 Handler 的全面用法指南&#xff1a; 一、Handler 的基本原理 Handler 基于消息队列(MessageQueue)和循环器(Looper)工作&#xff…

UE5学习笔记 FPS游戏制作33 游戏保存

文章目录 核心思想创建数据对象创建UIUI参数和方法打开UI存档文件的位置可以保存的数据类型 核心思想 UE自己有保存游戏的功能&#xff0c;核心节点&#xff0c;类似于json操作&#xff0c;需要一个数据类的对象来进行保存和读取 创建存档 加载存档 保存存档 创建数据对象…

【蓝桥杯】 枚举和模拟练习题

系列文章目录 蓝桥杯例题 枚举和模拟 文章目录 系列文章目录前言一、好数&#xff1a; 题目参考&#xff1a;核心思想&#xff1a;代码实现&#xff1a; 二、艺术与篮球&#xff1a; 题目参考&#xff1a;核心思想&#xff1a;代码实现: 总结 前言 今天距离蓝桥杯还有13天&…

大数据技术之Scala:特性、应用与生态系统

摘要 Scala 作为一门融合面向对象编程与函数式编程范式的编程语言&#xff0c;在大数据领域展现出独特优势。本文深入探讨 Scala 的核心特性&#xff0c;如函数式编程特性、类型系统以及与 Java 的兼容性等。同时&#xff0c;阐述其在大数据处理框架&#xff08;如 Apache Spa…

Linux信号——信号的产生(1)

注&#xff1a;信号vs信号量&#xff1a;两者没有任何关系&#xff01; 信号是什么&#xff1f; Linux系统提供的&#xff0c;让用户&#xff08;进程&#xff09;给其他进程发送异步信息的一种方式。 进程看待信号的方式&#xff1a; 1.信号在没有发生的时候&#xff0c;进…

数据结构和算法——汉诺塔问题

前言 先讲个故事&#xff0c;传说古代印度有三根黄金柱&#xff0c;64个石盘&#xff0c;需要将石盘从第一根移动到第三根上&#xff0c;规定每次只能移动一片&#xff0c;并且小盘在放置时必须在大盘上。 当石盘移动完毕时&#xff0c;世界就会毁灭。 汉诺塔——递归 接下来…

2023年3月全国计算机等级考试真题(二级C语言)

&#x1f600; 第1题 下列叙述中错误的是 A. 向量是线性结构 B. 非空线性结构中只有一个结点没有前件 C. 非空线性结构中只有一个结点没有后件 D. 只有一个根结点和一个叶子结点的结构必定是线性结构 概念澄清 首先&#xff0c;我们需要明确几个关键概念&#xf…

Kafka简单的性能调优

Kafka 的性能调优是一个系统性工程&#xff0c;需要从生产者、消费者、Broker 配置以及集群架构等多个层面进行综合调整。以下是一些关键的性能调优策略&#xff1a; 一、生产者性能优化 批量发送 batch.size&#xff1a;控制消息批量的最大字节数&#xff0c;默认值为 16KB。…

微前端 - 以无界为例

一、微前端核心概念 微前端是一种将单体前端应用拆分为多个独立子应用的架构模式&#xff0c;每个子应用可独立开发、部署和运行&#xff0c;具备以下特点&#xff1a; 技术栈无关性&#xff1a;允许主应用和子应用使用不同框架&#xff08;如 React Vue&#xff09;。独立部…

企业级日志分析平台: ELK 集群搭建指南

前言&#xff1a;在当今数字化时代&#xff0c;数据已经成为企业决策的核心驱动力。无论是日志分析、用户行为追踪&#xff0c;还是实时监控和异常检测&#xff0c;高效的数据处理和可视化能力都至关重要。ELK&#xff08;Elasticsearch、Logstash、Kibana&#xff09;作为全球…

1.2-WAF\CDN\OSS\反向代理\负载均衡

WAF&#xff1a;就是网站应用防火墙&#xff0c;有硬件类、软件类、云WAF&#xff1b; 还有网站内置的WAF&#xff0c;内置的WAF就是直接嵌在代码中的安全防护代码 硬件类&#xff1a;Imperva、天清WAG 软件&#xff1a;安全狗、D盾、云锁 云&#xff1a;阿里云盾、腾讯云WA…

MybatisPlus(SpringBoot版)学习第四讲:常用注解

目录 1.TableName 1.1 问题 1.2 通过TableName解决问题 1.3 通过全局配置解决问题 2.TableId 2.1 问题 2.2 通过TableId解决问题 2.3 TableId的value属性 2.4 TableId的type属性 2.5 雪花算法 1.背景 2.数据库分表 ①垂直分表 ②水平分表 1>主键自增 2>取…

第二届计算机网络和云计算国际会议(CNCC 2025)

重要信息 官网&#xff1a;www.iccncc.org 时间&#xff1a;2025年4月11-13日 地点&#xff1a;中国南昌 简介 第二届计算机网络和云计算国际会议&#xff08;CNCC 2025&#xff09;将于2025年4月11-13日在中国南昌召开。围绕“计算机网络”与“云计算”展开研讨&#xff…

【大模型基础_毛玉仁】5.4 定位编辑法:ROME

目录 5.4 定位编辑法&#xff1a;ROME5.4.1 知识存储位置1&#xff09;因果跟踪实验2&#xff09;阻断实验 5.4.2 知识存储机制5.4.3 精准知识编辑1&#xff09;确定键向量2&#xff09;优化值向量3&#xff09;插入知识 5.4 定位编辑法&#xff1a;ROME 定位编辑&#xff1a;…

横扫SQL面试——连续性登录问题

横扫SQL面试 &#x1f4cc; 连续性登录问题 在互联网公司的SQL面试中&#xff0c;连续性问题堪称“必考之王”。&#x1f4bb;&#x1f50d; 用户连续登录7天送优惠券&#x1f31f;&#xff0c;服务器连续报警3次触发熔断⚠️&#xff0c;图书馆连续3天人流破百开启限流⚡” …

Spring AI Alibaba 对话记忆使用

一、对话记忆 (ChatMemory)简介 1、对话记忆介绍 ”大模型的对话记忆”这一概念&#xff0c;根植于人工智能与自然语言处理领域&#xff0c;特别是针对具有深度学习能力的大型语言模型而言&#xff0c;它指的是模型在与用户进行交互式对话过程中&#xff0c;能够追踪、理解并利…

vdi模式是什么

‌VDI模式&#xff08;Virtual Desktop Infrastructure&#xff09;是一种基于服务器的计算模型&#xff0c;其核心思想是将所有计算和存储资源集中在服务器上&#xff0c;用户通过前端设备&#xff08;如瘦客户机&#xff09;访问服务器上的虚拟桌面‌‌ VDI模式的工作原理 在…

【分布式】深入剖析 Sentinel 限流:原理、实现

在当今分布式系统盛行的时代&#xff0c;流量的剧增给系统稳定性带来了巨大挑战。Sentinel 作为一款强大的流量控制组件&#xff0c;在保障系统平稳运行方面发挥着关键作用。本文将深入探讨 Sentinel 限流的原理、实现方案以及其优缺点&#xff0c;助力开发者更好地运用这一工具…