【问题标题】:How to get C# Enum description from value? [duplicate]如何从值中获取 C# 枚举描述? [复制]
【发布时间】:2011-02-08 15:43:36
【问题描述】:

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

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

我找到了这段代码,用于根据枚举检索描述

public static string GetEnumDescription(Enum value)
{
    FieldInfo fi = value.GetType().GetField(value.ToString());

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

    if (attributes != null && attributes.Any())
    {
        return attributes.First().Description;
    }

    return value.ToString();
}

这使我可以编写如下代码:

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

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

【问题讨论】:

标签: c# enums


【解决方案1】:

更新

Unconstrained Melody 库不再维护;已放弃对Enums.NET 的支持。

在 Enums.NET 中你会使用:

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

原帖

我在Unconstrained Melody 中以通用、类型安全的方式实现了这一点 - 你会使用:

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

这个:

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

我意识到核心答案只是从 intMyEnum 的演员表,但如果你正在做大量的枚举工作,那么值得考虑使用 Unconstrained Melody :)

【讨论】:

  • “值”不是一个整数吗?那么,Enums.GetDescription((MyEnum)value) 不只是将 int 转换为 MyEnum 吗?
  • @davekaro:它将 int 转换为 MyEnum - 但您无法使用任何非枚举调用它,包括“枚举”引用。基本上它就像你的代码,但有一些泛型魔法。
  • @JonSkeet 我在 code.google.com/p/unconstrained-melody/downloads/… 的 Enums.cs 中没有看到这个方法
  • @tom:它可能不是最新的“发布”版本,但它在源:code.google.com/p/unconstrained-melody/source/browse/trunk/…
  • @AlexZhukovskiy:我怀疑是这样,虽然我没有尝试过。您可能需要使用import="dnxcore450" 或其他。当 .NET Core 1.0 发布时,我会尽量记住更新包以确保它适用于 netstandard1.0。
【解决方案2】:

我将接受答案的代码放在一个通用扩展方法中,因此它可以用于各种对象:

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 属性的类,代码可以这样使用:

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

【讨论】:

  • string classDesc = myInstance.SomeProperty.DescriptionAttr();这是行不通的!假设你有 class Test { public int TestInt {get;放;} }。所以如果你调用 new Test().TestInt.DescriptionAttr() 你会得到空引用异常 - 0.GetType().GetField("0")
【解决方案3】:

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

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

现在我可以写了:

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

注意:将上面的“枚举”替换为您的班级名称

【讨论】:

  • To 表示转换为该类型。也许GetDescription 会是一个更好的名字?
【解决方案4】:

您不能以通用方式轻松做到这一点:您只能将整数转换为特定类型的枚举。正如 Nicholas 所展示的,如果您只关心一种枚举,这是一个微不足道的转换,但如果您想编写一个可以处理不同类型枚举的通用方法,事情会变得有点复杂。您需要一种方法:

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

但这会导致编译器错误“int 无法转换为 TEnum”(如果您解决此问题,“TEnum 无法转换为 Enum”)。所以你需要通过向对象插入强制转换来欺骗编译器:

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

您现在可以调用它来获取手头任何类型枚举的描述:

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

【讨论】:

  • “GetEnumDescription(1);”怎么样比 GetEnumDescription((MyEnum)1); 更好?
  • @davekaro:像这样实现,并没有那么好,但是基于泛型的更健壮的实现可以在没有显式转换的情况下做到这一点,所以如果数字没有,你不会冒未处理的异常的风险'实际上不匹配任何枚举值。
  • 有趣。只是为了向未来的读者澄清:如果数字与枚举值之一不匹配(您可以说“MyEnum value = (MyEnum)5;”并且该行将执行得很好,但是你会在原始问题中实现的 GetEnumDescription() 的第一行轰炸(因为 GetField() 将返回 null,因为它找不到与该值匹配的字段)。(为了防止这种情况,我们d 需要先检查 Enum.IsDefined() 并返回 null 或空字符串,或者自己抛出 ArgumentOutOfRangeException。)
【解决方案5】:
int value = 1;
string description = Enumerations.GetEnumDescription((MyEnum)value);

C# 中 enum 的默认基础数据类型是 int,您可以直接转换它。

【讨论】:

  • 为什么我在 .Net 框架中找不到任何 Enumerations 类?
  • Enumerations类是提问者自己写的,GetEnumDescription()函数在问题中。
  • 更好的方法是使用扩展方法。为此,请将Enumerations.GetEnumDescriptionEnum value 参数转换为this Enum value,然后像string description = ((MyEnum)value).GetEnumDescription() 一样调用它
  • 字符串描述=Enum.GetName(typeof(MyEnum), value);
  • 在问题中。它也在上面的评论中,我说它在问题中。只需阅读问题,就可以了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-21
  • 1970-01-01
  • 2012-10-15
相关资源
最近更新 更多