C#给枚举加自定义特性详解
通常我们需要定义一组特定值。采用枚举再好不过了。它可以让我们很方便直观的管理一组固定的值。如果我们需要对应输出枚举值的汉语意思或者颜色样式等,我们可以这样实现:
首先定义一个枚举类
enum @enum
{
Update = 1,
Insert = 2
}
方式一(if语句)
if (@enum == 1)
{
Console.Write("更新");
}
else (@enum == 2){
Console.Write("新增");
}
方式二(switch语句)
switch(@enum)
{
case 1:
Console.Write("更新");
break;
case 2:
Console.Write("新增");
break;
}
方式三(采用字典)
Dictionary<int, string> dic = new Dictionary<int, string>
{
[1] = "更新",
[2] = "新增"
};
Console.Write(dic[@enum]);
现在我们用一种更加优雅的方式来实现,给枚举加特性
在System.ComponentModel命名空间下有一个特性Description,用来指定属性或事件的描述。
enum @enum
{
[Description("修改")]
Update = 1,
[Description("新增")]
Insert = 2
}
我们可以写一个扩展,用来获取Description特性,这用反射来读取Description的值,这个是复用性的
/// <summary>
/// 获取特性 (DescriptionAttribute) 的说明;如果未使用该特性,则返回枚举的名称。可指定的默认值。
/// </summary>
/// <param name="enum"></param>
/// <param name="def">默认值</param>
/// <returns></returns>
public static string Description(this Enum @enum, string def = "")
{
Type enumType = @enum.GetType();
int value = int.Parse(Enum.Format(enumType, Enum.Parse(enumType, @enum.ToString()), "d"));
FieldInfo fieldInfo = enumType.GetField(Enum.GetName(enumType, value));
if (fieldInfo.GetCustomAttribute(typeof(DescriptionAttribute), false) is DescriptionAttribute descriptionAttribute)
{
return descriptionAttribute.Description;
}
return def != "" ? def : @enum.ToString();
}
那么在使用的时候我们将可以很方便的获取枚举值对应的描述信息
@enum.Update.Description();
这样每次使用都只需要这一句代码便可调出枚举值的描述信息那么,如果还有其它需求怎么办,比方说,这个枚举值还需要有代表色,样式等用来渲染HTML的属性怎么办,这里就用到了自定义特性,我们先说说怎么自定义特性。其实很简单。
新建一个类,注意所有的特性类必须继承自 Attribute,代码如下:
/// <summary>
/// 指定属性的样式
/// </summary>
public class ClassAttribute : Attribute
{
/// <summary>
/// 样式
/// </summary>
public string Class { get; set; }
/// <summary>
/// 样式
/// </summary>
/// <param name="value"></param>
public ClassAttribute(string value)
{
Class = value;
}
}
这样一个自定义特性就建好了,那么调用的方法,和Description一样。但是如果每次添加一个自定义特性都得建立一个调取特性值的方法,是不是很累。我们要记住面向对象的三大特性之封装。我们再写一个扩展,这里用到了反射和泛型。
/// <summary>
/// 获取指定特性的值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="enum"></param>
/// <param name="def">默认值</param>
/// <returns></returns>
public static String GetAttribute<T>(this Enum @enum, String def = "") where T : Attribute
{
Type type = @enum.GetType();
MemberInfo[] memInfo = type.GetMember(@enum.ToString());
object[] attributes = memInfo[0].GetCustomAttributes(typeof(T), false);
return (attributes.Length > 0) ? attributes[0].ToString() : def;
}
我们需要更改一下枚举
enum @enum
{
[Description("修改"),Class("className")]
Update = 1,
[Description("新增"),Class("className")]
Insert = 2
}
在使用的时候我们将可以很方便的获取到自定义特性的值
@enum.Update.GetAttribute<ClassAttribute>();
使用的时候注意引用关系。使用的时候根据实际需求做相应的调整。
作者:虾米哥
微信公众号:IT虾米,左侧为二维码
个人技术网站-IT虾米网:http://www.itxm.cn
个人技术网站-编程符号网:http://www.itfh.cn
个人技术网站-IT干货网:http://www.itgh.cn
新浪微博:https://weibo.com/u/2814576687
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
标签:
.NET
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)