如何使用Generics创建一种从枚举中创建IEnumerable的方法?

时间:2012-09-16 14:41:46

标签: c#

给出这样的枚举:

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

public enum House {
    OneFloor    = 1,
    TwoFloors = 2
}

我使用以下代码给我一个IEnumerable:

City[] values = (City[])Enum.GetValues(typeof(City)); 
var valuesWithNames = from value in values                       
   select new { value = (int)value, name = value.ToString() }; 

代码工作得非常好但是我必须在很多枚举中执行此操作。有没有办法可以创建一种通用的方法呢?

3 个答案:

答案 0 :(得分:3)

使用Jon Skeet的unconstrained melody

using UnconstrainedMelody;

您可以将枚举值放入Dictionary<int, string>,然后枚举它们:

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

但你可能甚至不需要这样做。为什么不直接枚举值:

foreach (var value in Enums.GetValues<City>())
{
    Console.WriteLine("{0}: {1}", (int)value, value);
}

答案 1 :(得分:1)

为什么不:

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

    }

所以你可以使用:

var result = GetValues<City>();

如果您想将约束通用T设为enum,因为enum 不能直接用作通用约束,而是enum继承自接口IConvertible,相信这种方式是可以的:

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

IEnumerable<object>替换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());
}

编辑:作为Magnus的评论,如果您需要确定项目的顺序,Dictionary不是选项。定义自己的强类型会更好。

答案 2 :(得分:1)

此功能可能对您有所帮助:

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()));
}

用法:

var values = GetValues<City>();