2010-04-16 28 views
279

可能重复:
Getting attributes of Enum’s value如何从值中获取C#Enum描述?

我有描述一个枚举的属性是这样的:

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 = 
     (DescriptionAttribute[])fi.GetCustomAttributes(
     typeof(DescriptionAttribute), 
     false); 

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

这让我写这样的代码:

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

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

+0

(!属性= NULL)永远是真实的,否则是多余的。描述是System.ComponentModel – Jeff 2014-07-17 23:00:46

+1

。正是我想要的。我知道这会很简单!现在,如果stackoverflow会让我接受这个答案......它说我需要等待7分钟。 – 2015-12-21 15:10:52

回答

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

默认在C#中的enum基础数据类型为int,你可以只投它。

+2

完美所需的命名空间为 – davekaro 2010-04-16 01:52:16

+41

为什么我在.Net框架中找不到任何Enumerations类? – 2013-12-26 17:56:30

+53

Enumerations类是提问者自己写的,GetEnumDescription()函数在问题中。 – 2013-12-29 17:03:46

5

你不能用通用的方式轻松做到这一点:你只能将整数转换为特定类型的枚举。正如尼古拉斯所表明的,如果你只关心一种枚举,那么这是一个微不足道的表现,但是如果你想写一个可以处理不同类型枚举的泛型方法,事情会变得更复杂一些。你想沿着线的方法:

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

但这会导致编译器错误“诠释不能转换为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); 
+0

如何“GetEnumDescription (1);”比GetEnumDescription((MyEnum)1)更好; ? – davekaro 2010-04-16 02:09:12

+0

@davekaro:像这样实现,并不是那么好,但基于泛型的更强大的实现可以在没有显式强制转换的情况下执行此操作,因此如果该数字实际上不匹配任何枚举值。 – Aaronaught 2010-04-16 02:15:46

+0

有趣。只是为了澄清未来的读者:如果数字不符合枚举值之一(可以说“MyEnum value =(MyEnum)5;”,那么一行就不会在明确的转换中得到未处理的异常执行得很好,但你会在原始问题中实现GetEnumDescription()的第一行,因为GetField()会返回null,因为它找不到与该值匹配的字段)(为了防止这种情况, d需要首先检查Enum.IsDefined(),并返回null或一个空字符串,或者只是自己抛出一个ArgumentOutOfRangeException。) – 2010-04-16 02:48:22

68

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

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

此:

  • 确保(与泛型类型约束),该值确实是一个枚举值
  • 避免了拳击在当前解决方案
  • 缓存所有的描述,以避免使用在每次调用
  • 反射有一堆的其他方法,包括从描述

我认识的核心答案是刚刚从一个intMyEnum投解析值的能力,但如果你做了很多枚举的工作,这是值得我们思考的使用约束旋律:)

+0

是不是“值”是一个整数?所以,Enums.GetDescription((MyEnum)值)只是将int转换为MyEnum? – davekaro 2010-04-16 12:20:12

+0

@davekaro:它将int转换为MyEnum - 但是你不能用任何非枚举来调用它,包括一个“Enum”引用。基本上它就像你的代码,但是有一些泛型魔术 – 2010-04-16 13:06:20

+1

@JonSkeet我在枚举中看不到这种方法s.cs在https://code.google.com/p/unconstrained-melody/downloads/detail?name=UnconstrainedMelody-0.0.0.2-src.zip&can=2&q= – tom 2013-09-13 19:14:49

19

为了更方便使用,我写了一个通用的扩展:

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

注:代替 “枚举” 上面有你的类名

50

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

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属性将enum一样,代码可以食用这样的:

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

string classDesc = myInstance.SomeProperty.DescriptionAttr();这是行不通的!假设你有类Test {public int TestInt {get;设置;}}。因此,如果您将调用新的Test()。TestInt.DescriptionAttr(),您将获得空引用异常 - 0.GetType()。GetField(“0”) – Vladimirs 2013-12-12 13:34:30