问题描述
在.NET/C#程序开发中,是否有方法获取枚举中的描述信息,而不是枚举的名称或者值本身呢?比如我们有如下的枚举:
using System.ComponentModel; // DescriptionAttribute所在的命名空间
enum FunkyAttributesEnum
{
[Description("枚举的描述1")]
NameWithoutSpaces1,
[Description("枚举的描述2")]
NameWithoutSpaces2
}
以上枚举,我们获取枚举的值是比较容易的,如:
Array values = System.Enum.GetValues(typeof(FunkyAttributesEnum));
foreach (int value in values)
Tuple.Value = Enum.GetName(typeof(FunkyAttributesEnum), value);
但是,现在的需求是需要通过一个枚举值,获取到枚举的对应描述信息,在.NET/C#程序开发中,我们应该如何来实现呢?
方案一
以下几个方法可以获取枚举的属性信息,如:
var type = typeof(FunkyAttributesEnum);
var memInfo = type.GetMember(FunkyAttributesEnum.NameWithoutSpaces1.ToString());
var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
var description = ((DescriptionAttribute)attributes[0]).Description;
方案二
创建一个静态扩展方法,并且是泛型的静态扩展方法,用以获取我们需要的枚举泛型属性信息,如:
public static class EnumHelper
{
public static T GetAttributeOfType<T>(this Enum enumVal) where T:System.Attribute
{
var type = enumVal.GetType();
var memInfo = type.GetMember(enumVal.ToString());
var attributes = memInfo[0].GetCustomAttributes(typeof(T), false);
return (attributes.Length > 0) ? (T)attributes[0] : null;
}
}
调用示例:
string desc = myEnumVariable.GetAttributeOfType<DescriptionAttribute>().Description;
方案三
同样是一个泛型的静态扩展方法,此方法使用LINQ
来实现,如:
public static Expected GetAttributeValue<T, Expected>(this Enum enumeration, Func<T, Expected> expression)
where T : Attribute
{
T attribute =
enumeration
.GetType()
.GetMember(enumeration.ToString())
.Where(member => member.MemberType == MemberTypes.Field)
.FirstOrDefault()
.GetCustomAttributes(typeof(T), false)
.Cast<T>()
.SingleOrDefault();
if (attribute == null)
return default(Expected);
return expression(attribute);
}
调用示例:
string description = targetLevel.GetAttributeValue<DescriptionAttribute, string>(x => x.Description);
方案四
另外一个关于读取枚举属性信息的静态扩展方法:
using System;
using System.ComponentModel;
public static class EnumExtensions {
public static T GetAttribute<T>(this Enum value) where T : Attribute {
var type = value.GetType();
var memberInfo = type.GetMember(value.ToString());
var attributes = memberInfo[0].GetCustomAttributes(typeof(T), false);
return (T)attributes[0];
}
public static string ToName(this Enum value) {
var attribute = value.GetAttribute<DescriptionAttribute>();
return attribute == null ? value.ToString() : attribute.Description;
}
}
使用示例:
using System.ComponentModel;
public enum Days {
[Description("Sunday")]
Sun,
[Description("Monday")]
Mon,
[Description("Tuesday")]
Tue,
[Description("Wednesday")]
Wed,
[Description("Thursday")]
Thu,
[Description("Friday")]
Fri,
[Description("Saturday")]
Sat
}
调用:
Console.WriteLine(Days.Mon.ToName());
或者
var day = Days.Mon;
Console.WriteLine(day.ToName());
方案五
另一个基于LINQ
的读取枚举属性信息的静态扩展方法:
public static DisplayAttribute GetDisplayAttributesFrom(this Enum enumValue, Type enumType)
{
return enumType.GetMember(enumValue.ToString())
.First()
.GetCustomAttribute<DisplayAttribute>();
}
调用示例:
public enum ModesOfTransport
{
[Display(Name = "Driving", Description = "Driving a car")] Land,
[Display(Name = "Flying", Description = "Flying on a plane")] Air,
[Display(Name = "Sea cruise", Description = "Cruising on a dinghy")] Sea
}
void Main()
{
ModesOfTransport TransportMode = ModesOfTransport.Sea;
DisplayAttribute metadata = TransportMode.GetDisplayAttributesFrom(typeof(ModesOfTransport));
Console.WriteLine("Name: {0} \nDescription: {1}", metadata.Name, metadata.Description);
}
输出结果:
Name: Sea cruise
Description: Cruising on a dinghy
版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。
发表评论
登录用户才能发表评论, 请 登 录 或者 注册