How can I use Generics to create a way of making an IEnumerable from an enum?

后端 未结 3 1964
遇见更好的自我
遇见更好的自我 2021-01-18 09:33

Given an enum like this:

public enum City {
    London    = 1,
    Liverpool  = 20,
    Leeds       = 25
}

public enum House {
    OneFloor    = 1,
    TwoF         


        
相关标签:
3条回答
  • 2021-01-18 09:50

    This function might help you:

    public static IEnumerable<KeyValuePair<int, string>> GetValues<T>() where T : struct
    {
            var t = typeof(T);
            if(!t.IsEnum)
                throw new ArgumentException("Not an enum type");
    
            return Enum.GetValues(t).Cast<T>().Select (x => 
                   new KeyValuePair<int, string>(
                       (int)Enum.ToObject(t, x), 
                        x.ToString()));
    }
    

    Usage:

    var values = GetValues<City>();
    
    0 讨论(0)
  • 2021-01-18 09:54

    Why not:

        IEnumerable<object> GetValues<T>()
        {
            return Enum.GetValues(typeof (T))
                       .Cast<T>()
                       .Select(value => new {     
                                                 value = Convert.ToInt32(value),
                                                 name = value.ToString()
                                             });
    
        }
    

    So you can use:

    var result = GetValues<City>();
    

    If you would like to make constraint generic T as enum, because enum cannot be used as generic contraint directly, but enum inherits from interface IConvertible, believe this way is okay:

    IEnumerable<object> GetValues<T>() where T: struct, IConvertible
    {}
    

    To replace IEnumerable<object> by Dictionary:

    Dictionary<int, string> GetValues<T>() where T :  struct, IConvertible
    {
        return Enum.GetValues(typeof (T)).Cast<T>()
                   .ToDictionary(value => Convert.ToInt32(value),
                                 value => value.ToString());
    }
    

    Edit: As Magnus's comment, if you need to make sure the order of items, Dictionary is not the option. Define your own strong type would be better.

    0 讨论(0)
  • 2021-01-18 10:05

    Use Jon Skeet's unconstrained melody.

    using UnconstrainedMelody;
    

    You can put your enum values into a Dictionary<int, string> and then enumerate over them:

    var valuesAsDictionary = Enums.GetValues<City>()
                                  .ToDictionary(key => (int)key, value => value.ToString());
    

    But you probably don't even need to do that. Why not just enumerate over the values directly:

    foreach (var value in Enums.GetValues<City>())
    {
        Console.WriteLine("{0}: {1}", (int)value, value);
    }
    
    0 讨论(0)
提交回复
热议问题