首页 / C#开发 / 正文

[C#].NET/C#程序开发获取枚举属性的方法有哪些呢?

3623 发布于: 2018-02-27 读完约需12分钟

.NET&&C#程序开发

问题描述

在.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

版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。

上一篇: [C#].NET/C#程序开发如何为一个数组添加值有哪些方法?

下一篇: [C#].NET/C#程序开发中反序列化XML文档有哪些方法?

本文永久链接码友网 » [C#].NET/C#程序开发获取枚举属性的方法有哪些呢?

分享扩散:

发表评论

登录用户才能发表评论, 请 登 录 或者 注册