如何从值中获取C#枚举描述?

How to get C# Enum description from value?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Getting attributes of Enum’s value

我有一个具有如下描述属性的枚举:

1
2
3
4
5
6
7
8
public enum MyEnum
{
    Name1 = 1,
    [Description("Here is another")]
    HereIsAnother = 2,
    [Description("Last one")]
    LastOne = 3
}

我找到了这个基于枚举检索描述的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static string GetEnumDescription(Enum value)
{
    FieldInfo fi = value.GetType().GetField(value.ToString());

    DescriptionAttribute[] attributes =
        (DescriptionAttribute[])fi.GetCustomAttributes(
        typeof(DescriptionAttribute),
        false);

    if (attributes != null &&
        attributes.Length > 0)
        return attributes[0].Description;
    else
        return value.ToString();
}

这允许我编写如下代码:

1
2
var myEnumDescriptions = from MyEnum n in Enum.GetValues(typeof(MyEnum))
                         select new { ID = (int)n, Name = Enumerations.GetEnumDescription(n) };

我想做的是,如果我知道枚举值(例如1),如何检索描述?换句话说,如何将整数转换为"枚举值"以传递给我的getDescription方法?


1
2
int value = 1;
string description = Enumerations.GetEnumDescription((MyEnum)value);

c中的enum的默认基础数据类型是int,您只需强制转换即可。


更新

不受约束的旋律库不再被维护;支持被放弃,取而代之的是enums.net。

在Enums.net中,您将使用:

1
string description = ((MyEnum)value).AsString(EnumFormat.Description);

原帖

我以一种通用的、类型安全的方式在不受约束的旋律中实现了这一点—您可以使用:

1
string description = Enums.GetDescription((MyEnum)value);

这是:

  • 确保(使用泛型类型约束)值确实是枚举值
  • 避免在当前解决方案中装箱
  • 缓存所有描述以避免对每个调用使用反射
  • 有许多其他方法,包括从描述中解析值的能力

我知道核心答案只是从一个intMyEnum的演员阵容,但是如果你做了大量的枚举工作,就值得考虑使用不受约束的旋律:)


我将接受的答案中的代码放在一个通用扩展方法中,这样它就可以用于所有类型的对象:

1
2
3
4
5
6
7
8
9
10
public static string DescriptionAttr<T>(this T source)
{
    FieldInfo fi = source.GetType().GetField(source.ToString());

    DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(
        typeof(DescriptionAttribute), false);

    if (attributes != null && attributes.Length > 0) return attributes[0].Description;
    else return source.ToString();
}

使用与原始日志中类似的枚举,或者使用description属性修饰其属性的任何其他类,可以这样使用代码:

1
2
string enumDesc = MyEnum.HereIsAnother.DescriptionAttr();
string classDesc = myInstance.SomeProperty.DescriptionAttr();


为了使这个更容易使用,我编写了一个通用扩展:

1
2
3
4
public static string ToDescription<TEnum>(this TEnum EnumValue) where TEnum : struct
{
    return Enumerations.GetEnumDescription((Enum)(object)((TEnum)EnumValue));
}

现在我可以写:

1
2
3
        MyEnum my = MyEnum.HereIsAnother;
        string description = my.ToDescription();
        System.Diagnostics.Debug.Print(description);

注意:用类名替换上面的"枚举"


不能用一般的方法轻松地完成这项工作:只能将整数转换为特定类型的枚举。正如Nicholas所展示的,如果您只关心一种枚举,那么这是一个微不足道的强制转换,但是如果您想编写一个能够处理不同类型枚举的泛型方法,事情会变得更加复杂。您需要一个符合以下条件的方法:

1
2
3
4
public static string GetEnumDescription<TEnum>(int value)
{
  return GetEnumDescription((Enum)((TEnum)value));  // error!
}

但这会导致一个编译器错误,即"in t不能转换为t enum"(如果解决此问题,则"t enum不能转换为enum")。因此,您需要通过向对象插入强制转换来愚弄编译器:

1
2
3
4
public static string GetEnumDescription<TEnum>(int value)
{
  return GetEnumDescription((Enum)(object)((TEnum)(object)value));  // ugly, but works
}

现在,您可以调用此函数来获取现有枚举类型的描述:

1
2
GetEnumDescription<MyEnum>(1);
GetEnumDescription<YourEnum>(2);