特性与反射总结

一、概念对比

特性(Attributes)

是什么:给代码元素贴的"标签"或"注解"
作用:为代码添加额外信息(元数据)
时机:编译时和运行时都可以读取

反射(Reflection)

是什么:在运行时"查看"和"操作"代码的能力
作用:动态获取类型信息、创建对象、调用方法
时机:只能在运行时使用

二、关系:特性 + 反射 = 强大功能

工作流程:

text

1. 用特性给代码"贴标签"(编译时) 2. 用反射读取这些"标签"(运行时) 3. 根据标签信息执行相应操作

三、基本使用格式

1. 定义自定义特性

csharp

// 1. 继承Attribute类 // 2. 使用AttributeUsage指定应用范围 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] public class CustomAttribute : Attribute { // 属性 public string Description { get; set; } public int Version { get; set; } // 构造方法 public CustomAttribute(string description) { Description = description; Version = 1; } }

2. 使用特性

csharp

[Custom("学生类", Version = 2)] public class Student { [Custom("姓名属性")] public string Name { get; set; } [Custom("学习方法")] public void Study() { } }

3. 用反射读取特性

csharp

// 获取类型信息 Type type = typeof(Student); // 读取类上的特性 CustomAttribute classAttr = (CustomAttribute)type.GetCustomAttribute(typeof(CustomAttribute)); if (classAttr != null) { Console.WriteLine($"类描述: {classAttr.Description}"); Console.WriteLine($"版本: {classAttr.Version}"); } // 读取属性上的特性 foreach (var property in type.GetProperties()) { var attr = property.GetCustomAttribute<CustomAttribute>(); if (attr != null) { Console.WriteLine($"属性 {property.Name}: {attr.Description}"); } } // 读取方法上的特性 foreach (var method in type.GetMethods()) { var attr = method.GetCustomAttribute<CustomAttribute>(); if (attr != null) { Console.WriteLine($"方法 {method.Name}: {attr.Description}"); } }

四、AttributeUsage参数详解

1. AttributeTargets(可以贴在哪里)

csharp

// 单个目标 AttributeTargets.Class // 类 AttributeTargets.Method // 方法 AttributeTargets.Property // 属性 AttributeTargets.Field // 字段 AttributeTargets.Constructor // 构造方法 AttributeTargets.Struct // 结构体 AttributeTargets.Interface // 接口 AttributeTargets.Enum // 枚举 AttributeTargets.Parameter // 参数 AttributeTargets.Assembly // 程序集 // 多个目标(用 | 连接) AttributeTargets.Class | AttributeTargets.Method // 所有成员 AttributeTargets.All

2. AllowMultiple(是否可以贴多个)

csharp

AllowMultiple = false // 只能贴一个(默认) AllowMultiple = true // 可以贴多个 // 示例: [MyAttr("标签1")] [MyAttr("标签2")] // 只有当AllowMultiple=true时才允许 public class MyClass { }

3. Inherited(是否被子类继承)

csharp

Inherited = true // 子类可以继承特性(默认) Inherited = false // 子类不继承特性

五、反射常用方法

1. 获取类型信息

csharp

// 三种方式获取Type对象 Type type1 = typeof(Student); // 编译时已知类型 Type type2 = obj.GetType(); // 运行时对象 Type type3 = Type.GetType("命名空间.类名"); // 通过字符串 // 常用属性和方法 type.Name // 类名 type.FullName // 完整名称(含命名空间) type.Namespace // 命名空间 type.BaseType // 父类类型 type.IsClass // 是否是类 type.IsPublic // 是否是public

2. 获取成员信息

csharp

// 获取所有方法 MethodInfo[] methods = type.GetMethods(); // 获取所有属性 PropertyInfo[] properties = type.GetProperties(); // 获取所有字段 FieldInfo[] fields = type.GetFields(); // 获取所有构造方法 ConstructorInfo[] constructors = type.GetConstructors();

3. 动态创建对象和调用方法

csharp

// 1. 创建对象 object obj = Activator.CreateInstance(type); // 2. 设置属性值 PropertyInfo prop = type.GetProperty("Name"); prop.SetValue(obj, "张三"); // 3. 获取属性值 string name = (string)prop.GetValue(obj); // 4. 调用方法 MethodInfo method = type.GetMethod("Study"); method.Invoke(obj, null); // 无参数方法 // 5. 调用带参数的方法 MethodInfo method2 = type.GetMethod("SetAge"); method2.Invoke(obj, new object[] { 20 });

六、完整示例:数据验证系统

1. 定义验证特性

csharp

[AttributeUsage(AttributeTargets.Property)] public class ValidationAttribute : Attribute { public string ErrorMessage { get; set; } public bool Required { get; set; } public int MinLength { get; set; } = 0; public int MaxLength { get; set; } = int.MaxValue; }

2. 使用特性标记模型

csharp

public class Student { [Validation(Required = true, MinLength = 2, ErrorMessage = "姓名不能为空且至少2个字符")] public string Name { get; set; } [Validation(Required = true, ErrorMessage = "年龄必须填写")] public int Age { get; set; } [Validation(Required = true, MaxLength = 11, ErrorMessage = "手机号格式不正确")] public string Phone { get; set; } }

3. 反射读取并验证

csharp

public class Validator { public static List<string> Validate(object obj) { List<string> errors = new List<string>(); Type type = obj.GetType(); foreach (PropertyInfo property in type.GetProperties()) { // 获取特性 ValidationAttribute attr = property.GetCustomAttribute<ValidationAttribute>(); if (attr != null) { // 获取属性值 object value = property.GetValue(obj); // 验证必填 if (attr.Required && (value == null || string.IsNullOrEmpty(value.ToString()))) { errors.Add(attr.ErrorMessage); continue; } // 验证长度 if (value != null) { string strValue = value.ToString(); if (strValue.Length < attr.MinLength || strValue.Length > attr.MaxLength) { errors.Add(attr.ErrorMessage); } } } } return errors; } }

4. 使用验证器

csharp

Student student = new Student { Name = "张", // 长度不够 Age = 0, Phone = "123456789012" // 长度超过 }; var errors = Validator.Validate(student); foreach (var error in errors) { Console.WriteLine(error); }

七、总结表格

方面特性(Attribute)反射(Reflection)
目的添加元数据读取和操作元数据
时机编译时定义运行时使用
使用方式用 [] 声明用 Type 类操作
常见用途配置、验证、序列化动态加载、插件系统
性能几乎没有影响较慢,避免频繁使用

八、最佳实践

1. 特性使用原则

csharp

// 好的做法 [AttributeUsage(AttributeTargets.Property)] // 明确目标 public class MyAttribute : Attribute { public string Description { get; } // 只读属性 public MyAttribute(string description) // 构造方法 { Description = description; } } // 使用 [My("这是一个重要的属性")] public string ImportantProperty { get; set; }

2. 反射使用原则

csharp

// 缓存Type信息(提高性能) private static readonly Type _cachedType = typeof(MyClass); // 使用泛型减少类型转换 public T CreateInstance<T>() where T : new() { return new T(); // 比反射创建快 } // 必要时才用反射 if (needDynamic) { // 使用反射 } else { // 使用静态代码 }

九、一句话总结

特性是贴标签,反射是读标签,两者结合实现动态编程。

text

工作流程: 1. 设计特性 → 定义标签格式 2. 标注代码 → 贴上标签 3. 反射读取 → 运行时查看标签 4. 执行逻辑 → 根据标签决定行为

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

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

相关文章

AI agents协作分析社交网络:评估公司的社会影响力

AI agents协作分析社交网络&#xff1a;评估公司的社会影响力关键词&#xff1a;AI agents、社交网络分析、公司社会影响力评估、协作机制、数据挖掘摘要&#xff1a;本文聚焦于利用AI agents协作分析社交网络来评估公司的社会影响力。首先介绍了研究背景、目的和预期读者等内容…

linux主机安全加固指南!

一、修改密码策略1、cp /etc/login.defs /etc/login.defs.bak2、vi /etc/login.defsPASS_MAX_DAYS 90 &#xff08;用户的密码不过期最多的天数&#xff09;PASS_MIN_DAYS 0 &#xff08;密码修改之间最小的天数&#xff09;PASS_MIN_LEN 8 &#xff08;密码最小长度&am…

2026.1.14 Linux计划任务与进程

任务进程ps查看进程选项a 显示当前终端下所有进程信息&#xff0c;包括其他用户的进程u 显示以用户为主的格式输出进程信息x 显示当前用户在所有终端下的进程信息-e 显示系统内所有进程信息-f 使用完整的格式显示进程信息-l 使用完整…

大规模语言模型在自动诗歌创作中的探索

大规模语言模型在自动诗歌创作中的探索关键词&#xff1a;大规模语言模型、自动诗歌创作、自然语言处理、诗歌生成算法、深度学习摘要&#xff1a;本文深入探讨了大规模语言模型在自动诗歌创作领域的应用。首先介绍了相关背景&#xff0c;包括研究目的、预期读者和文档结构等。…

AI应用架构师必知:优化AI系统故障诊断的方案

AI应用架构师必知&#xff1a;优化AI系统故障诊断的方案 引言 痛点引入&#xff1a;AI系统故障诊断的“三座大山” 作为AI应用架构师&#xff0c;你是否遇到过这样的场景&#xff1f; 线上推理服务突然延迟飙升&#xff0c;用户投诉不断&#xff0c;但日志里只有“timeout”报错…

AUTOSAR如何自动化生成BSW、RTE、AP模块并进行一致性校验?

AUTOSAR这个框架中&#xff0c;BSW&#xff08;Basic Software&#xff09;、RTE&#xff08;Runtime Environment&#xff09;和AP&#xff08;Application&#xff09;模块各司其职&#xff0c;构成了整个软件系统的核心。BSW负责硬件抽象和基础服务&#xff0c;比如通信、诊…

计算机毕业设计springboot互联网就医系统 基于Spring Boot的互联网医疗服务平台设计与实现 Spring Boot框架下的在线医疗系统开发与应用

计算机毕业设计springboot互联网就医系统r2097 &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。随着信息技术的飞速发展&#xff0c;互联网已经深刻改变了人们的生活方式&#xf…

SRAM 芯片容量计算及常见型号速查表

IS62WV51216 SRAM 芯片容量计算及常见型号速查表 IS62WV51216 的总容量为 1MB&#xff08;字节&#xff09;&#xff0c;计算核心是拆解型号中的关键参数&#xff0c;结合 SRAM 容量计算公式推导。 一、型号参数拆解 ISSI 公司的 IS62WV 系列 SRAM 型号命名有明确规律&#xff…

救命神器8个AI论文工具,专科生搞定毕业论文+格式规范!

救命神器8个AI论文工具&#xff0c;专科生搞定毕业论文格式规范&#xff01; 专科生的毕业论文救星&#xff0c;AI 工具如何改变你的写作方式&#xff1f; 对于很多专科生来说&#xff0c;毕业论文不仅是一次学术训练&#xff0c;更是一场与时间、压力和知识盲区的较量。尤其是…

【卫星】全球导航卫星系统GNSS中的欺骗与欺骗检测算法,模拟载体在正常GNSS导航和GNSS欺骗攻击下的运动状态,通过IMU+GNSS融合定位,最终实现欺骗检测与结果分析附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#x1f34…

单片机基础知识 -- HADDR

STM32中HADDR的完整解析 一、HADDR的基础定义&#xff08;必记核心&#xff09; HADDR AHB Peripheral Address Bus&#xff0c;中文全称&#xff1a;AHB外设地址总线。 它是STM32单片机内部 高速AHB总线&#xff08;Advanced High-performance Bus&#xff09; 的专属地址总线…

深度测评 自考必备 9款一键生成论文工具TOP9推荐

深度测评 自考必备 9款一键生成论文工具TOP9推荐 自考论文写作的高效助手&#xff1a;为何需要一份权威测评 随着自考人数逐年增长&#xff0c;论文写作已成为许多考生必须面对的挑战。从选题构思到资料收集&#xff0c;再到内容撰写与格式调整&#xff0c;整个过程耗时且复杂。…

【电力系统】基于混合粒子群优化-禁忌搜索优化在光伏丰富的配电网络中用于优化电池储能系统的位置、容量和调度附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#x1f34…

一次内网开发环境访问方式的改进实践:使用 FRP 替代远程桌面

一次内网开发环境访问方式的改进实践&#xff1a;使用 FRP 替代远程桌面 一、背景 在公司项目中&#xff0c;经常会遇到这样一种开发环境限制&#xff1a;项目内网服务器禁止直接访问外网为了在该环境下进行开发和调试&#xff0c;常见的做法是&#xff1a; 准备一台 可以联网的…

在Markdown文档中添加目录的方法

在Markdown文档中添加目录有多种方法&#xff0c;下面介绍几种常用的方式&#xff1a; 一、自动生成目录&#xff08;部分编辑器/平台支持&#xff09; 1. 使用 [TOC] 标记&#xff08;Typora、部分GitHub项目等&#xff09; [toc] # 标题1 ## 标题2 ### 标题32. 使用插件/扩…

计算机网络经典问题透视:媒体播放器与媒体服务器的AB面

摘要&#xff1a; 在我们日常的数字生活中&#xff0c;无论是观看一场激动人心的体育直播&#xff0c;还是沉浸于一部高清电影&#xff0c;背后都离不开两个默默无闻的功臣&#xff1a;媒体播放器&#xff08;Media Player&#xff09;和媒体服务器&#xff08;Media Server&am…

MySQL事务隔离级别:从并发混乱到数据一致性守护者

引言&#xff1a;一个银行系统的并发困境想象一下&#xff0c;你正在开发一个银行转账系统。当用户A向用户B转账时&#xff0c;系统需要执行两个操作&#xff1a;从A账户扣款&#xff0c;向B账户加款。在并发环境下&#xff0c;如果没有适当的控制&#xff0c;可能会发生这样的…

亲测好用!10款一键生成论文工具测评:本科生毕业论文必备清单

亲测好用&#xff01;10款一键生成论文工具测评&#xff1a;本科生毕业论文必备清单 2026年学术写作工具测评&#xff1a;为何需要一份精准推荐清单 随着人工智能技术的不断进步&#xff0c;越来越多的本科生在撰写毕业论文时开始依赖AI辅助工具。然而&#xff0c;面对市场上琳…

巴西木培养养护的原则

巴西木 可以把根一直泡在水中么&#xff1f;不建议将巴西木的根部长期泡在水中。巴西木&#xff08;学名&#xff1a;Dracaena fragrans&#xff0c;又称幸运木、香龙血树&#xff09;虽然是一种比较耐水湿的植物&#xff0c;但长期将根部完全浸泡在水中会导致烂根&#xff0c;…

2025_NIPS_Follow-the-Perturbed-Leader Nearly Achieves Best-of-Both-Worlds for the m-Set Semi-Bandit

文章核心总结与翻译 一、主要内容 本文聚焦m-集半臂赌博机问题(从d个臂中精确选择m个臂的组合半臂赌博机场景),研究了Follow-the-Perturbed-Leader(FTPL)算法在对抗性和随机性环境下的性能。在对抗性环境中,已知Follow-the-Regularized-Leader(FTRL)算法能达到O(√(n…