2009-06-23 60 views
4

我具有表示系统中的所有材料汇编代码的枚举:如何从描述中获得枚举值?

public enum EAssemblyUnit 
{ 
    [Description("UCAL1")] 
    eUCAL1, 
    [Description("UCAL1-3CP")] 
    eUCAL13CP, 
    [Description("UCAL40-3CP")] 
    eUCAL403CP, // ... 
} 

在传统代码在系统的另一部分,我有标记有相匹配的枚举描述的字符串对象。鉴于其中的一个字符串,获取枚举值的最简单方法是什么?我设想是这样的:

public EAssemblyUnit FromDescription(string AU) 
{ 
    EAssemblyUnit eAU = <value we find with description matching AU> 
    return eAU; 
} 

回答

8

你会需要通过枚举所有的静态字段进行迭代(这就是他们如何存储在反射)找到为每一个Description属性...当你发现了正确的一个,获得该领域的价值。

例如:(这是一般只是为了重复使用于不同的枚举)

public static T GetValue<T>(string description) 
{ 
    foreach (var field in typeof(T).GetFields()) 
    { 
     var descriptions = (DescriptionAttribute[]) 
       field.GetCustomAttributes(typeof(DescriptionAttribute), false); 
     if (descriptions.Any(x => x.Description == description)) 
     { 
      return (T) field.GetValue(null); 
     } 
    } 
    throw new SomeException("Description not found"); 
} 

显然,你会想,如果你这样做,甚至略有频繁缓存的说明如:

public static class DescriptionDictionary<T> where T : struct 
{ 
    private static readonly Dictionary<string, T> Map = 
     new Dictionary<string, T>(); 

    static DescriptionDictionary() 
    { 
     if (typeof(T).BaseType != typeof(Enum)) 
     { 
      throw new ArgumentException("Must only use with enums"); 
     } 
     // Could do this with a LINQ query, admittedly... 
     foreach (var field in typeof(T).GetFields 
       (BindingFlags.Public | BindingFlags.Static)) 
     { 
      T value = (T) field.GetValue(null); 
      foreach (var description in (DescriptionAttribute[]) 
       field.GetCustomAttributes(typeof(DescriptionAttribute), false)) 
      { 
       // TODO: Decide what to do if a description comes up 
       // more than once 
       Map[description.Description] = value; 
      } 
     } 
    } 

    public static T GetValue(string description) 
    { 
     T ret; 
     if (Map.TryGetValue(description, out ret)) 
     { 
      return ret; 
     } 
     throw new WhateverException("Description not found"); 
    } 
} 
+1

哎,真的很希望为“这里有一个方便的功能就像一个词典<>的说明和值之间”。也许我会建立一个静态保存该字典的类,并在第一次需要时填充它...? – 2009-06-23 15:26:22

+0

是的 - 你需要的核心部分是我的答案,它给出了描述。哦,它的东西...我现在写。挂在:) – 2009-06-23 15:29:40

0
public EAssemblyUnit FromDescription(string AU) 
{ 
    EAssemblyUnit eAU = Enum.Parse(typeof(EAssemblyUnit), AU, true); 
    return eAU; 
} 
0

您也可以使用Humanizer˚F或者那个。要获得描述你可以使用:

EAssemblyUnit.eUCAL1.Humanize(); 

,并得到枚举从描述回你可以使用

"UCAL1".DehumanizeTo<EAssemblyUnit>(); 

免责声明:我Humanizer的创造者。