Enum to Dictionary in C#

I have searched this online, but I can't find the answer I am looking for.

Basically I have the following enum:

public enum typFoo : int
{
itemA : 1,
itemB : 2
itemC : 3
}

How can I convert this enum to Dictionary so that it stores in the following Dictionary?

Dictionary<int,string> myDic = new Dictionary<int,string>();

And myDic would look like this:

1, itemA
2, itemB
3, itemC

Any ideas?

94069 次浏览

You can enumerate over the enum descriptors:

Dictionary<int, string> enumDictionary = new Dictionary<int, string>();


foreach(var name in Enum.GetNames(typeof(typFoo))
{
enumDictionary.Add((int)((typFoo)Enum.Parse(typeof(typFoo)), name), name);
}

That should put the value of each item and the name into your dictionary.

If you need only the name you don't have to create that dictionary at all.

This will convert enum to int:

 int pos = (int)typFoo.itemA;

This will convert int to enum:

  typFoo foo = (typFoo) 1;

And this will retrun you the name of it:

 ((typFoo) i).toString();

Try:

var dict = Enum.GetValues(typeof(fooEnumType))
.Cast<fooEnumType>()
.ToDictionary(t => (int)t, t => t.ToString() );

Using reflection:

Dictionary<int,string> mydic = new Dictionary<int,string>();


foreach (FieldInfo fi in typeof(typFoo).GetFields(BindingFlags.Public | BindingFlags.Static))
{
mydic.Add(fi.GetRawConstantValue(), fi.Name);
}

See: How do I enumerate an enum in C#?

foreach( typFoo foo in Enum.GetValues(typeof(typFoo)) )
{
mydic.Add((int)foo, foo.ToString());
}

Adapting Ani's answer so that it can be used as a generic method (thanks, toddmo):

public static Dictionary<int, string> EnumDictionary<T>()
{
if (!typeof(T).IsEnum)
throw new ArgumentException("Type must be an enum");
return Enum.GetValues(typeof(T))
.Cast<T>()
.ToDictionary(t => (int)(object)t, t => t.ToString());
}

+1 to Ani. Here's the VB.NET version

Here's the VB.NET version of Ani's answer:

Public Enum typFoo
itemA = 1
itemB = 2
itemC = 3
End Enum


Sub example()


Dim dict As Dictionary(Of Integer, String) = System.Enum.GetValues(GetType(typFoo)) _
.Cast(Of typFoo)() _
.ToDictionary(Function(t) Integer.Parse(t), Function(t) t.ToString())
For Each i As KeyValuePair(Of Integer, String) In dict
MsgBox(String.Format("Key: {0}, Value: {1}", i.Key, i.Value))
Next


End Sub

Additional example

In my case, I wanted to save the path of important directories and store them in my web.config file's AppSettings section. Then I created an enum to represent the keys for these AppSettings...but my front-end engineer needed access to these locations in our external JavaScript files. So, I created the following code-block and placed it in our primary master page. Now, each new Enum item will auto-create a corresponding JavaScript variable. Here's my code block:

    <script type="text/javascript">
var rootDirectory = '<%= ResolveUrl("~/")%>';
// This next part will loop through the public enumeration of App_Directory and create a corresponding JavaScript variable that contains the directory URL from the web.config.
<% Dim App_Directories As Dictionary(Of String, App_Directory) = System.Enum.GetValues(GetType(App_Directory)) _
.Cast(Of App_Directory)() _
.ToDictionary(Of String)(Function(dir) dir.ToString)%>
<% For Each i As KeyValuePair(Of String, App_Directory) In App_Directories%>
<% Response.Write(String.Format("var {0} = '{1}';", i.Key, ResolveUrl(ConfigurationManager.AppSettings(i.Value))))%>
<% next i %>
</script>

NOTE: In this example, I used the name of the enum as the key (not the int value).

Use:

public static class EnumHelper
{
public static IDictionary<int, string> ConvertToDictionary<T>() where T : struct
{
var dictionary = new Dictionary<int, string>();


var values = Enum.GetValues(typeof(T));


foreach (var value in values)
{
int key = (int) value;


dictionary.Add(key, value.ToString());
}


return dictionary;
}
}

Usage:

public enum typFoo : int
{
itemA = 1,
itemB = 2,
itemC = 3
}


var mydic = EnumHelper.ConvertToDictionary<typFoo>();
  • Extension method
  • Conventional naming
  • One line
  • C# 7 return syntax (but you can use brackets in those old legacy versions of C#)
  • Throws an ArgumentException if the type is not System.Enum, thanks to Enum.GetValues
  • IntelliSense will be limited to structs (no enum constraint is available yet)
  • Allows you to use enum to index into the dictionary, if desired.
public static Dictionary<T, string> ToDictionary<T>() where T : struct
=> Enum.GetValues(typeof(T)).Cast<T>().ToDictionary(e => e, e => e.ToString());

Another extension method that builds on Arithmomaniac's example:

    /// <summary>
/// Returns a Dictionary&lt;int, string&gt; of the parent enumeration. Note that the extension method must
/// be called with one of the enumeration values, it does not matter which one is used.
/// Sample call: var myDictionary = StringComparison.Ordinal.ToDictionary().
/// </summary>
/// <param name="enumValue">An enumeration value (e.g. StringComparison.Ordinal).</param>
/// <returns>Dictionary with Key = enumeration numbers and Value = associated text.</returns>
public static Dictionary<int, string> ToDictionary(this Enum enumValue)
{
var enumType = enumValue.GetType();
return Enum.GetValues(enumType)
.Cast<Enum>()
.ToDictionary(t => (int)(object)t, t => t.ToString());
}