如何从值得到c#枚举描述?

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

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

我发现这段代码用于基于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();
}

这允许我编写如下代码:

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

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

626803 次浏览
int value = 1;
string description = Enumerations.GetEnumDescription((MyEnum)value);

c#中enum的默认底层数据类型是int,你可以强制转换它。

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

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

但这会导致编译器错误,“int不能被转换为TEnum”(如果你绕过这个问题,“TEnum不能被转换为Enum”)。所以你需要通过向object插入类型转换来欺骗编译器:

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

你现在可以调用这个来获取手边任何类型枚举的描述:

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

更新

不再维护Unconstrained Melody库;对枚举。网的支持已被放弃。

在枚举。NET你会使用:

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

最初的发布

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

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

这样的:

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

我意识到核心答案只是从int转换到MyEnum,但如果你正在做大量枚举工作,值得考虑使用Unconstrained Melody:)

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

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);

注意:用你的类名替换上面的“Enumerations”

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

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();