使用泛型将枚举转换为字典

JGi*_*tin 0 c# linq generics

即时通讯试图创建一个我可以调用的方法,它将Dictionary<int,string>从枚举中返回一个类型字典 .

我想使用泛型.

到目前为止这是我的代码......

public class Enums
{
    public static Dictionary<int, string> GetEnumDictionary<T>()
    {
        return Enum.GetValues(typeof(T)))
           .Cast<typeof(T)>()
           .ToDictionary(t => (int)t, t => t.ToString());
    }

    /// <summary>
    /// Fuel Type Enum
    /// </summary>
    public enum FuelTypes
    {
        Petrol = 1,
        Diesel = 2,
        Hybrid = 3,
        Electric = 4
    }
}
Run Code Online (Sandbox Code Playgroud)

单元测试...

[TestClass]
public class EnumTests
{
    [TestMethod]
    public void TestGetEnumDictionary()
    {
        Dictionary<int, string> dict = new Dictionary<int, string>();
        dict = Enums.GetEnumDictionary<Enums.FuelTypes>();
        Assert.IsTrue(dict != null);
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到的恭维错误是

运算符'<'不能应用于'方法组'和'System.Type'类型的操作数

任何人都可以看到我的错误在哪里?

dig*_*All 6

GetEnumDictionary方法中有两个主要错误:

首先,Cast<typeof(T)>没有意义.这很简单Cast<T>.

然后,您不能简单地将类型T的值转换为int和int,但必须先将其强制转换为object.
所以,你应该像这样改变你的方法:

public static Dictionary<int, string> GetEnumDictionary<T>()
{
    return Enum.GetValues(typeof(T))
       .Cast<T>()
       .ToDictionary(t => (int)(object)t, t => t.ToString());
}
Run Code Online (Sandbox Code Playgroud)

但问题是你可以传递任何你想要的类型,甚至是非枚举类型.不幸的是,您不能将泛型类型限制为Enum,因此您需要在运行时检查它:

public static Dictionary<int, string> GetEnumDictionary<T>()
{
    if(!typeof(T).IsEnum)
       throw new ArgumentException("T is not an Enum type");
    return Enum.GetValues(typeof(T))
       .Cast<T>()
       .ToDictionary(t => (int)(object)t, t => t.ToString());
}
Run Code Online (Sandbox Code Playgroud)

编辑:

正如svick正确指出的那样,枚举的基础类型可能不同于int.例如,它不适用于这样的枚举:

enum MyEnum : long
{
   Foo,
   Bar,
}
Run Code Online (Sandbox Code Playgroud)

为了更安全,也许你应该在运行时检查:

public static Dictionary<int, string> GetEnumDictionary<T>()
{
    if (!typeof(T).IsEnum)
        throw new ArgumentException("T is not an Enum type");
    if (Enum.GetUnderlyingType(typeof(T)) != typeof(int))
        throw new ArgumentException("The underlying type of the enum T is not Int32");
    return Enum.GetValues(typeof(T))
        .Cast<T>()
        .ToDictionary(t => (int)(object)t, t => t.ToString());
}
Run Code Online (Sandbox Code Playgroud)

最后一点.

您可以更改代码以支持具有适合的整数值的枚举Int32.实际上你可以简单地使用一个Convert.ToInt32()而不是使用直接强制转换,int或者如在其他答案中正确显示的那样,你可以利用该IConvertible界面.
但是,在我看来,它并没有给你带来很多好处.由于这种方法不是真正的类型安全,你应该在知道自己在做什么时使用它; 因此,如果你想要一个"long-enum"(例如)的字典,只需使用/ make另一种方法......