枚举字符串值并按值查找枚举

我希望有一个类似下面的枚举,然后有一个类似于Util.FindFruitByValue(“A”)的方法返回枚举Apple。 这是因为缩写存储在数据库中,我需要在从db读取后将它们转换为适当的枚举。 这是可能的还是我需要为它创建一个单独的类? 请告诉我。 提前致谢。

public enum Fruit { Apple = "A" Banana = "B" Cherry = "C" } 

更新:这就像一个查找表,但区别在于值是字符串而不是int。 我通过读取数据库中的值来填充业务对象,我想使用具有固定值的类型而不是字符串。

我通过使用枚举上的Description属性解决了这个问题。 解决方案如下。 我使用扩展方法来获取描述。 获取描述的代码来自此链接http://blog.spontaneouspublicity.com/post/2008/01/17/Associating-Strings-with-enums-in-C.aspx 。 谢谢你的回复。

  public enum Fruit { [Description("Apple")] A, [Description("Banana")] B, [Description("Cherry")] C } public static class Util { public static T StringToEnum(string name) { return (T)Enum.Parse(typeof(T), name); } public static string ToDescriptionString(this 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(); } } 

您可以将值放在Dictionary以有效地查找它们:

 Dictionary fruitValues = new Dictionary(); fruitValues.Add("A", Fruit.Apple); fruitValues.Add("B", Fruit.Banana); fruitValues.Add("C", Fruit.Cherry); 

抬头:

 string dataName = "A"; Fruit f = fruitValues[dataName]; 

如果该值可能不存在:

 string dataName = "A"; Fruit f; if (fruitValues.TryGetValue(dataName, out f)) { // got the value } else { // there is no value for that string } 

我写了一个库来处理这个问题。 它本来只是为了做相反的事情(从和Enum返回一个字符串值)但是一旦我写了,能够将一个字符串解析回它的Enum,只是一小步。

该库名为EnumStringValues,可从VS中的nuget获得(包页也在这里: https ://www.nuget.org/packages/EnumStringValues)SourceCode在GitHub上: https : //github.com/Brondahl/EnumStringValues

欢迎提出想法和意见。 灵感显然来自这里其他答案中引用的广为人知的属性方法。

使用Hashtable怎么样?

对不起,我忽略了OP的Enum的定义。 显然,Enum值必须是数字类型,因此OP的定义不起作用。

我有一个想法是使用char值作为Enum值,例如

 public enum Fruit { Apple = 65, //"A", Banana = 66, // "B", Cherry = 67 //"C" } 

根据Convert.ToInt32(’A’) – 不知道如何处理区分大小写。 然后,通过强制转换获取正确的结果。 我还在玩一个例子,很高兴听到一些建议。

好的,抱歉延误了。 以下是对此的更多信息:

 public static class EnumConverter { public static T ToEnum(char charToConvert, out bool success) { try { int intValue = Convert.ToInt32(charToConvert); if (Enum.IsDefined(typeof(T), intValue)) { success = true; return (T)Enum.ToObject(typeof(T), intValue); } } catch (ArgumentException ex) { // Use your own Exception Management Here } catch (InvalidCastException ex) { // Use your own Exception Management Here } success = false; return default(T); } } 

用法:

 bool success = false; Fruit selected = EnumConverter.ToEnum('A', out success); if (success) { // go for broke } 

我创建了一个DynamicEnum类,它可以非常轻松地将枚举进出域和数据存储库。

 public abstract class DynamicEnum : IEquatable, IComparable where T : DynamicEnum, new() { #region Instance public int PathCode { get; private set; } public string PathValue { get; private set; } protected DynamicEnum() { } protected DynamicEnum(int pathCode, string pathValue) { PathCode = pathCode; PathValue = PathValue; } #region IEquatable Members public bool Equals(T other) { return PathCode == other.PathCode; } #endregion public override bool Equals(object obj) { return Equals(obj as T); } public override int GetHashCode() { return PathCode.GetHashCode(); } #region IComparable Members public int CompareTo(T other) { return PathCode.CompareTo(other.PathCode); } #endregion #endregion #region Class / Static static DynamicEnum() { // Despite appearances, static methods are not really inherited by // child classes. This means when the mapping fields below are accessed // by an implementing class the CLR does not see it as a method on that // class. In the event that the implementing class's static constructor // hasn't been called yet, it will not be called at that point since // technically no static method/property or instance of the implementing // class has been used. Working around this by creating an instance here // which causes the derived class's static constructor to be called // beforehand. This could alternately be solved by moving the default 'enum' // value initialization out of the implementing classes to the Global.asax // where the database 'enum' values are optionally loaded. new T(); } public static void Initialize(IEnumerable statuses) { IntoDomainMapping = statuses.ToDictionary(x => x.PathValue, x => x); IntoDBMapping = IntoDomainMapping.ToDictionary(x => x.Value, x => x.Key); } public static Dictionary IntoDomainMapping { get; protected set; } public static Dictionary IntoDBMapping { get; protected set; } #endregion #region Operator Overloads public static bool operator ==(DynamicEnum s1, T s2) { return s1.Equals(s2); } public static bool operator !=(DynamicEnum s1, T s2) { return !s1.Equals(s2); } public static bool operator >(DynamicEnum s1, T s2) { return s1.CompareTo(s2) > 0; } public static bool operator <(DynamicEnum s1, T s2) { return s1.CompareTo(s2) < 0; } public static bool operator >=(DynamicEnum s1, T s2) { return s1.CompareTo(s2) >= 0; } public static bool operator <=(DynamicEnum s1, T s2) { return s1.CompareTo(s2) <= 0; } #endregion } 

这是“Enum”课程

  public class ResourcePath : DynamicEnum { public ResourcePath() { } public ResourcePath(int pathCode, string pathValue) : base(pathCode, pathValue) { } static ResourcePath() { Initialize(new List { new ResourcePath(1, "customer.list"), new ResourcePath(1, "customer.create"), new ResourcePath(1, "customer.info"), new ResourcePath(1, "customer.update"), new ResourcePath(1, "customer.delete"), }); } public static ResourcePath Deleted { get { return ResourcePath.IntoDomainMapping["DE"]}; } } 

最后基本用法

 var resource = GetAllResources().Where(e => e.PathCode == pathCode).firstOrDefault(); 

我知道这是一个老post,但我有类似的问题,我昨天找到了解决方案。

您可以使用类型安全枚举模式,如下文所述:

https://stackoverflow.com/a/424414/1257584