C#中自定义 Attribute 特性类:从定义到运行时反射读取,附吴亦凡、罗志祥示例及注意点
在C#里,`Attribute` 是一种特殊的类,可用于为程序中的元素(像类、方法、属性等)添加额外元数据信息。这些元数据能在运行时被读取,从而实现各种功能,如代码分析、反射等。 在你的代码中,`Attribute` 起到了如下作用: 1. 定义自定义特性类:借助继承 `Attribute` 类,你能够定义自己的特性类。在代码里,`SomeThing` 类继承自 `Attribute`,这意味着 `SomeThing` 是一个自定义特性类。 2. 特性类的属性和构造函数:`SomeThing` 类包含两个私有字段 `name` 和 `date`,并且有对应的公共属性 `Name` 和 `Date`。它还有一个构造函数,用来初始化这些属性。 3. 应用特性:你可以使用自定义特性类为其他程序元素添加元数据。在代码中,`Test1` 类、`Test2` 类和 `Sex` 枚举都应用了 `SomeThing` 特性,同时传入了相应的参数。 下面是一个简单示例,展示如何在运行时通过反射读取这些特性信息: ```csharp using System; // 自定义特性类 [AttributeUsage(AttributeTargets.All)] public class SomeThing : Attribute { private string name; private string date; public string Name { get { return name; } set { name = value; } } public string Date { get { return date; } set { date = value; } } public SomeThing(string n, string d) { Name = n; Date = d; } } // 应用特性的类 [SomeThing("吴亦凡", "2025.6.10")] class Test1 { } // 应用特性的类 [SomeThing("罗志祥", "2025.6.10")] class Test2 { } // 应用特性的枚举 [SomeThing("罗志祥", "2025.6.10")] enum Sex { } class Program { static void Main() { // 获取 Test1 类的特性信息 Type test1Type = typeof(Test1); SomeThing test1Attribute = (SomeThing)Attribute.GetCustomAttribute(test1Type, typeof(SomeThing)); if (test1Attribute != null) { Console.WriteLine($"Test1 类的特性信息 - 姓名: {test1Attribute.Name}, 日期: {test1Attribute.Date}"); } // 获取 Test2 类的特性信息 Type test2Type = typeof(Test2); SomeThing test2Attribute = (SomeThing)Attribute.GetCustomAttribute(test2Type, typeof(SomeThing)); if (test2Attribute != null) { Console.WriteLine($"Test2 类的特性信息 - 姓名: {test2Attribute.Name}, 日期: {test2Attribute.Date}"); } // 获取 Sex 枚举的特性信息 Type sexType = typeof(Sex); SomeThing sexAttribute = (SomeThing)Attribute.GetCustomAttribute(sexType, typeof(SomeThing)); if (sexAttribute != null) { Console.WriteLine($"Sex 枚举的特性信息 - 姓名: {sexAttribute.Name}, 日期: {sexAttribute.Date}"); } } } ``` 额外需要注意的逻辑点 1. 自定义特性类的名称通常以 `Attribute` 结尾,不过在应用特性时可以省略这个后缀。 2. 在使用反射读取特性信息时,要保证特性类的访问修饰符是公有的,不然可能无法访问。 3. 特性类的属性和构造函数参数类型必须是常量表达式、类型字面量或者 `Type` 类型,不能是变量。 ######[AI写代码神器 | 894点数解答 | 2025-06-10 15:14:59]
- Java实现链表反转:迭代与递归双解法详解及开发实战指南(DeepSeek | 1409点数解答 | 2026-03-15 15:09:29)22
- Android开发自定义 Handler :七大策略有效规避内存泄漏!(百度文心 | 526点数解答 | 2023-11-09 17:34:21)283
- C++ 实现正方形黑白瓦片图案最小转换方法求解(字节豆包 | 817点数解答 | 2025-11-25 19:03:09)69
- 深入分析:OpenGL ES 着色器版本处理与语法兼容代码 (字节豆包 | 260点数解答 | 2024-10-19 19:42:17)299
- 深入解析 OpenGL Vertex 代码:实现不同版本着色器兼容性的秘诀(字节豆包 | 191点数解答 | 2024-10-19 19:43:44)283
- 深入剖析:OpenGL顶点着色器跨版本条件编译代码(讯飞星火 | 223点数解答 | 2024-10-19 19:50:37)364
- 深度剖析:OpenGL 着色器代码的顶点与纹理坐标计算逻辑及潜在错误(讯飞星火 | 424点数解答 | 2024-10-19 19:51:49)308
- 深度剖析:顶点着色器代码的功能与原理(讯飞星火 | 623点数解答 | 2024-10-26 18:47:09)228
- C++编程:冒泡排序函数模板、txtdata类与bindata类的实现及应用(GPT | 1551点数解答 | 2024-06-01 16:02:33)326
- C++:冒泡排序函数模板与文件读写类(txtdata、bindata)的实现及应用(GPT | 1941点数解答 | 2024-06-01 16:23:06)310
- 探寻数组中最长摆动子序列长度:思路剖析与代码优化(GPT | 758点数解答 | 2024-12-23 23:18:29)264
- 独家剖析:求解数组最长摆动子序列长度的代码实现与改进建议(GPT | 350点数解答 | 2024-12-23 23:20:54)261