C#秘密武器之特性
一、概述
Attribute说白了就是一个类而已,里边一般含有一些附加信息,或者一些特殊的处理逻辑,以便告诉编译器应用该特性的东东是个奇葩,需要特殊对待!
二、使用时的注意事项
2.1. Attribute是一个类,必须继承自System.Attribute
2.2 Attribute命名规范
Attribute命名一般以Attribute结尾, 但是在具体使用时候,可以省去Attribute这一后缀。加入定义了一个HelperAttribute, 具体使用的时候,可以这样写[Helper].
2.3 Attribute的使用限制
Attribute类在定义的时候,可以指定这个Attribute的应用范围,AttributeTargets枚举就列出了可以指定的范围,可以是class, field等;AllowMutiple为true或者false,意思就是是否让该特性在某个地方重复使用(比如在某一个类上使用多次);Inherited为true或者false,意思就是该特性是否会被应用该特性的类的子类继承。
2.4 Attribute中的参数赋值
位置参数(Attribute构造函数的参数):必填,且顺序要一致!
命名参数(Attribute中的其他字段或者属性):在使用时可以省略!
三、自定义一个Attribute并读取其值
举个栗子:
[AttributeUsage(AttributeTargets.Class, AllowMutiple=true, Inherited=false)]
public class BookAttribute:Attribute
{
public string Msg { get; set; }
public double Version = 1.0;
public MyFirstAttribute(string msg)
{
Msg= msg;
}
}
通过反射获取Attribute相关信息:
namespace TestAttribute {
//多次使用特性类
[Book("人民邮电")] [Book("北京")] class BookInfo { public string bookinfo = "图书信息"; //构造函数 public BookInfo() { } } }
static void Main(string[] args) { BookInfo bookinfo = new BookInfo(); MemberInfo typeinfo = typeof(BookInfo); object[] bookarr= typeinfo.GetCustomAttributes(typeof(BookAttribute), false); if (bookarr.GetLength(0) != 0) { BookAttribute bookattribute1 = (BookAttribute)bookarr[0]; BookAttribute bookattribute2 = (BookAttribute)bookarr[1]; Console.WriteLine(bookinfo.bookinfo); Console.WriteLine("出版社为:" + bookattribute1.Msg+ "城市为:" + bookattribute2.Msg); Console.ReadKey(); } }
四、学会使用一些.NET内置特性
举个栗子:
System.ObsoleteAttribute:告诉编译器某个方法已经过时,然后当编译器发现程序中有地方在使用这个用Obsolete标记过的方法时,就会给出一个警告信息。
public class TestClass
{
// 添加Obsolete特性
[Obsolete("请使用新的SendMsg(Message msg)重载方法")]
public static void ShowMsg()
{
Console.WriteLine("这是旧的SendMsg()方法");
}
}
private void button1_Click(object sender, EventArgs e)
{
TestClass.ShowMsg();
}
现在运行这段代码,我们会发现编译器给出了一个警告!
五、特性在枚举上的应用
enum Gender { [Description(“男”)] Man, [Description(“女”)] Woman };
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; namespace MyTools { /// <summary> /// 枚举帮助类 /// </summary> public static class EnumHelper { /// <summary> /// 获取枚举项的Attribute /// </summary> /// <typeparam name="T">自定义的Attribute</typeparam> /// <param name="source">枚举</param> /// <returns>返回枚举,否则返回null</returns> public static T GetCustomAttribute<T>(Enum source) where T : Attribute { Type sourceType = source.GetType(); string sourceName = Enum.GetName(sourceType, source); FieldInfo field = sourceType.GetField(sourceName); object[] attributes = field.GetCustomAttributes(typeof(T), false); foreach (object attribute in attributes) { if (attribute is T) return (T)attribute; } return null; } /// <summary> ///获取DescriptionAttribute描述 /// </summary> /// <param name="source">枚举</param> /// <returns>有description标记,返回标记描述,否则返回null</returns> public static string GetDescription(this Enum source) { var attr = GetCustomAttribute<System.ComponentModel.DescriptionAttribute>(source); if (attr == null) return null; return attr.Description; } public static EnumT GetValueByDescription<EnumT>(string description) { var type = typeof(EnumT); if (!type.IsEnum) throw new ArgumentException("This method is destinated for enum types only."); foreach (var enumName in Enum.GetNames(type)) { var enumValue = Enum.Parse(type, enumName); if (description == ((Enum)enumValue).GetDescription()) return (EnumType)enumValue; } throw new ArgumentException("There is no value with this description among specified enum type values."); } } }
使用方法:
Gender.Man.GetDescription()
注意MVC中特性的巧妙应用,改写!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述