Enumerations with String Values ​​and Search for Enumerations by Value

I want to have an enumeration like the following, and then a method like Util.FindFruitByValue ("A"), which returns the Apple enum. this is because the abbreviations are stored in the database, and I need to convert them to the corresponding enumerations after reading from db. Is this possible OR do I need to create a separate class for it? Please let me know. thanks in advance.

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

Update: this looks like a lookup table, but the difference in value is a string instead of an int. I populate a business object by reading the values ​​from the database, and I would like to use a type with fixed values ​​for the property of the object instead of a string.

+7
enums c #
source share
7 answers

I solved the problem using the Description attribute in the listing. The solution is as follows. I use the extension method to get the description. The code for the description is taken from this link http://blog.spontaneouspublicity.com/post/2008/01/17/Associating-Strings-with-enums-in-C.aspx . thank you for your responses.

  public enum Fruit { [Description("Apple")] A, [Description("Banana")] B, [Description("Cherry")] C } public static class Util { public static T StringToEnum<T>(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(); } } 
+19
source share

You can put values ​​in a Dictionary for efficient searches:

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

Search:

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

If the value may be missing:

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

I wrote a library that handles exactly this problem. It was originally intended only to do the opposite (return the string value from and Enum), but as soon as I wrote that being able to parse a string back into its Enum was only a short step.

The library is called EnumStringValues ​​and is available from nuget on VS (there is also a package page here: https://www.nuget.org/packages/EnumStringValues ) SourceCode is on GitHub here: https://github.com/Brondahl/EnumStringValues

Thoughts and comments are welcome. Inspiration obviously stems from the widespread Attribute approach mentioned in other answers here.

+2
source share

How about using a hashtable?

+1
source share

Sorry, I missed the definition of OP Enum. Obviously, Enum values ​​must be numeric, so the definition of OP will not work.

It seemed to me that you need to use the char value as an Enum value, for example.

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

According to Convert.ToInt32 ('A') - not sure what to do with case sensitivity. Then take the correct result by casting. I am still playing with an example, glad to hear some suggestions.

OK, sorry for the delay. Here is a bit more about this:

 public static class EnumConverter<T> { 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); } } 

Using:

 bool success = false; Fruit selected = EnumConverter<Fruit>.ToEnum('A', out success); if (success) { // go for broke } 
+1
source share

I made a small DynamicEnum class that makes it easy to pull enums into and out of a domain repository and data.

 public abstract class DynamicEnum<T> : IEquatable<T>, IComparable<T> where T : DynamicEnum<T>, 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<AreaStatus> 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<AreaStatus> 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 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 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<T> statuses) { IntoDomainMapping = statuses.ToDictionary(x => x.PathValue, x => x); IntoDBMapping = IntoDomainMapping.ToDictionary(x => x.Value, x => x.Key); } public static Dictionary<string, T> IntoDomainMapping { get; protected set; } public static Dictionary<T, string> IntoDBMapping { get; protected set; } #endregion #region Operator Overloads public static bool operator ==(DynamicEnum<T> s1, T s2) { return s1.Equals(s2); } public static bool operator !=(DynamicEnum<T> s1, T s2) { return !s1.Equals(s2); } public static bool operator >(DynamicEnum<T> s1, T s2) { return s1.CompareTo(s2) > 0; } public static bool operator <(DynamicEnum<T> s1, T s2) { return s1.CompareTo(s2) < 0; } public static bool operator >=(DynamicEnum<T> s1, T s2) { return s1.CompareTo(s2) >= 0; } public static bool operator <=(DynamicEnum<T> s1, T s2) { return s1.CompareTo(s2) <= 0; } #endregion } 

Here is the Enum class

  public class ResourcePath : DynamicEnum<ResourcePath> { public ResourcePath() { } public ResourcePath(int pathCode, string pathValue) : base(pathCode, pathValue) { } static ResourcePath() { Initialize(new List<ResourcePath> { 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"]}; } } 

Finally, the main use

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

I know this is an old post, but I had a similar problem, and yesterday I found a solution for it.

You can use a safe type enumeration template as described in this post:

stack overflow

0
source share

All Articles