开发者

Enum to dictionary

开发者 https://www.devze.com 2023-02-20 20:04 出处:网络
I want to implement an extension method which converts an enum to a dictionary: public static Dictionary<int, string> ToDictionary(this Enum @enum)

I want to implement an extension method which converts an enum to a dictionary:

public static Dictionary<int, string> ToDictionary(this Enum @enum)
{
    Type type1 = @enum.GetType();
    return Enum.GetValues(type1).Cast<type1>()
        //.OfType<typeof(@enum)>()
        .ToDictionary(e => Enum.GetName(@enum.GetType(), e));
}

开发者_如何学CWhy it doesn't compile?

An error:

"The type or namespace name 'type1' could not be found (are you missing a using directive or an assembly reference?)"


Jon Skeet has written everything you need ;)

But here you have your code that is working:

public static Dictionary<int, string> ToDictionary(this Enum @enum)
{
  var type = @enum.GetType();
  return Enum.GetValues(type).Cast<int>().ToDictionary(e => e, e => Enum.GetName(type, e));
}


Well, you're trying to use a variable of type Type as a generic type argument. You can't do that with generics, which are about compile-time types.

You can do it with reflection, but it would be better to make it a generic method. Unfortunately you can't constrain a generic type parameter to be an enum, although I have some hacks to work around that in Unconstrained Melody.

Failing that, you could use just a struct type constraint for a generic method which would be a good start.

Now, the next problem is that you're trying to get a Dictionary<int, string> - but the values of an enum aren't int values. They might be convertable to int values, but they aren't there immediately. You could use Convert.ToInt32 to do that, but you would have to do something.

Finally (for the moment) what would you expect to happen with an enum using a uint or long underlying type?


You can't use type1 as a generic parameter, because it is a variable, not a type.

The following code does something similar to what your code shows:

public static Dictionary<string, TEnum> ToDictionary<TEnum>()
    where TEnum : struct
{
    if (!typeof(TEnum).IsEnum)
        throw new ArgumentException("Type must be an enumeration");
    return Enum.GetValues(typeof(TEnum)).Cast<TEnum>().
            ToDictionary(e => Enum.GetName(typeof(TEnum), e));
}

Use it like this:

ToDictionary<Colors>()

But I am not really sure, this is, what you expected?

Additionally, it has one problem: You can pass any struct, not just enums and this will result in a runtime exception. See Jon's answer for more details about that.


Based on Daniel's solution:

public static SelectList ToSelectList<TEnum>(this HtmlHelper h) where TEnum : struct
{
    return new SelectList(FortunaExtension.ToDictionary<TEnum>(), "Key", "Value");
}


Here is the extension method I use to convert enumerations. The only difference is that I am returning IEnumerbale<KeyValuePair<int, int>> for my purpose:

public static IEnumerable<KeyValuePair<int, string>> ToListOfKeyValuePairs<TEnum>(this TEnum enumeration) where TEnum : struct
{
    return from TEnum e in Enum.GetValues(typeof(TEnum))
            select new KeyValuePair<int, string>
                (
                    (int)Enum.Parse(typeof(TEnum), e.ToString()),
                    Regex.Replace(e.ToString(), "[A-Z]", x => string.Concat(" ", x.Value[0])).Trim()
                );
}

It also adds spaces for the value.

Example:

enum Province
{
    BritishColumbia = 0,
    Ontario = 1
}

Usage:

<select>
<% foreach(var item in Province.BritishColumbia.ToListOfKeyValuePairs()){ %>
    <option value="<%=item.Key %>"><%=item.Value %></option>
<% } %>
</select>

Output:

<select>
    <option value="0">British Columbia</option>
    <option value="1">Ontario</option>
</select>

Though @Paul Ruane is correct I have found this to be a very useful extension method. It's not a perfect world.

0

精彩评论

暂无评论...
验证码 换一张
取 消