如何从价值中获取C#Enum描述?

dav*_*aro 364 c# enums

可能重复:
获取Enum值的属性

我有一个带有Description属性的枚举,如下所示:

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

我找到了一些用于根据Enum检索描述的代码

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();
}
Run Code Online (Sandbox Code Playgroud)

这允许我编写如下代码:

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

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

Nic*_*cki 344

int value = 1;
string description = Enumerations.GetEnumDescription((MyEnum)value);
Run Code Online (Sandbox Code Playgroud)

enumC#中的默认底层数据类型是a int,你可以直接转换它.

  • 为什么我在.Net框架中找不到任何Enumerations类? (76认同)
  • Enumerations类是提出问题的人自己写的,而GetEnumDescription()函数就在问题中. (74认同)
  • 更好的方法可能是使用扩展方法.为此,将"Enumerations.GetEnumDescription"的"Enum value"参数转换为"此Enum值",然后将其称为`string description =((MyEnum)value).GetEnumDescription()` (12认同)
  • string description = Enum.GetName(typeof(MyEnum),value); (6认同)
  • 这是问题所在.它也出现在上面的评论中,我在这个问题中说出来.只需阅读问题,就在那里. (3认同)
  • 完善.正是我想要的.我知道这很简单!现在,如果stackoverflow让我接受这个答案......它说我需要等待7分钟. (2认同)
  • 这对我不起作用-枚举不存在? (2认同)

Jon*_*eet 88

更新

无约束旋律图书馆不再维护; 支持被删除,有利于Enums.NET.

在Enums.NET中,您将使用:

string description = ((MyEnum)value).AsString(EnumFormat.Description);
Run Code Online (Sandbox Code Playgroud)

原帖

我在Unconstrained Melody中以通用的,类型安全的方式实现了这个- 你使用:

string description = Enums.GetDescription((MyEnum)value);
Run Code Online (Sandbox Code Playgroud)

这个:

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

我认识的核心答案是刚刚从投intMyEnum,但如果你做了很多枚举的工作,这是值得考虑使用无约束的旋律:)

  • @JonSkeet 我在 https://code.google.com/p/unconstrained-melody/downloads/detail?name=UnconstrainedMelody-0.0.0.2-src.zip&can=2&q= 的 Enums.cs 中没有看到这个方法 (2认同)
  • @tom:它可能不是最新的"已发布"版本,但它来自源代码:https://code.google.com/p/unconstrained-melody/source/browse/trunk/UnconstrainedMelody/Enums.cs (2认同)

小智 79

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

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();
}
Run Code Online (Sandbox Code Playgroud)

使用原始帖子中的枚举或其属性使用Description属性修饰的任何其他类,代码可以像这样使用:

string enumDesc = MyEnum.HereIsAnother.DescriptionAttr();
string classDesc = myInstance.SomeProperty.DescriptionAttr();
Run Code Online (Sandbox Code Playgroud)

  • string classDesc = myInstance.SomeProperty.DescriptionAttr(); 那样不行!假设您有类Test {public int TestInt {get; 设置;}}.因此,如果您将调用新的Test().TestInt.DescriptionAttr(),您将获得空引用异常 - 0.GetType().GetField("0") (4认同)

Dav*_*vid 30

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

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

现在我可以写:

        MyEnum my = MyEnum.HereIsAnother;
        string description = my.ToDescription();
        System.Diagnostics.Debug.Print(description);
Run Code Online (Sandbox Code Playgroud)

注意:将上面的"Enumerations"替换为您的班级名称

  • “To”意味着到该类型的转换。也许“GetDescription”会是一个更好的名字? (5认同)

ito*_*son 7

您不能以通用方式轻松执行此操作:您只能将整数转换为特定类型的枚举.正如尼古拉斯所表明的那样,如果你只关心一种枚举,这是一个微不足道的演员,但如果你想写一个能处理不同类型枚举的通用方法,事情会变得复杂一些.你想要一个方法:

public static string GetEnumDescription<TEnum>(int value)
{
  return GetEnumDescription((Enum)((TEnum)value));  // error!
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

GetEnumDescription<MyEnum>(1);
GetEnumDescription<YourEnum>(2);
Run Code Online (Sandbox Code Playgroud)