如何从System.Enum转换为基本整数?

时间:2009-05-26 01:17:30

标签: c# enums type-conversion

我想创建一个泛型方法,将任何System.Enum派生类型转换为相应的整数值,而不进行强制转换,最好不要解析字符串。

例如,我想要的是这样的:

// Trivial example, not actually what I'm doing.
class Converter
{
    int ToInteger(System.Enum anEnum)
    {
        (int)anEnum;
    }
}

但这似乎不起作用。 Resharper报告您无法将类型为“System.Enum”的表达式转换为“int”。

现在我已经提出了这个解决方案,但我宁愿提高效率。

class Converter
{
    int ToInteger(System.Enum anEnum)
    {
        return int.Parse(anEnum.ToString("d"));
    }
}

有什么建议吗?

9 个答案:

答案 0 :(得分:129)

如果你不想演员,

Convert.ToInt32()

可以做到这一点。

直接演员(通过(int)enumValue)是不可能的。请注意,这也是“危险的”,因为枚举可以有不同的基础类型(intlongbyte ...)。

更正式地说:System.EnumInt32没有直接的继承关系(虽然两者都是ValueType s),因此在类型系统中显式强制转换不正确

答案 1 :(得分:37)

我通过强制转换为对象然后转换为int来实现它:

public static class EnumExtensions
{
    public static int ToInt(this Enum enumValue)
    {
        return (int)((object)enumValue);
    }
}

这很丑陋,可能不是最好的方法。我会继续搞乱它,看看我能不能提出更好的东西......

编辑:即将发布的Convert.ToInt32(enumValue)也可以发布,并注意到MartinStettner打败了我。

public static class EnumExtensions
{
    public static int ToInt(this Enum enumValue)
    {
        return Convert.ToInt32(enumValue);
    }
}

测试:

int x = DayOfWeek.Friday.ToInt();
Console.WriteLine(x); // results in 5 which is int value of Friday

编辑2:在评论中,有人说这只适用于C#3.0。我刚刚在VS2005中对此进行了测试,并且有效:

public static class Helpers
{
    public static int ToInt(Enum enumValue)
    {
        return Convert.ToInt32(enumValue);
    }
}

    static void Main(string[] args)
    {
        Console.WriteLine(Helpers.ToInt(DayOfWeek.Friday));
    }

答案 2 :(得分:12)

如果您需要将任何枚举转换为其基础类型(并非所有枚举都由int支持),那么您可以使用:

return System.Convert.ChangeType(
    enumValue,
    Enum.GetUnderlyingType(enumValue.GetType()));

答案 3 :(得分:11)

为什么需要使用辅助方法重新发明轮子?将enum值转换为其基础类型是完全合法的。

打字少,而且在我看来更具可读性,使用......

int x = (int)DayOfWeek.Tuesday;

......而不是像......

int y = Converter.ToInteger(DayOfWeek.Tuesday);
// or
int z = DayOfWeek.Tuesday.ToInteger();

答案 4 :(得分:4)

从我的回答here

给定e如下:

Enum e = Question.Role;

然后这些工作:

int i = Convert.ToInt32(e);
int i = (int)(object)e;
int i = (int)Enum.Parse(e.GetType(), e.ToString());
int i = (int)Enum.ToObject(e.GetType(), e);

最后两个很难看。第一个应该更具可读性,但第二个更快。或者可能是一种扩展方法是最好的,两全其美。

public static int GetIntValue(this Enum e)
{
    return e.GetValue<int>();
}

public static T GetValue<T>(this Enum e) where T : struct, IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T>
{
    return (T)(object)e;
}

现在你可以致电:

e.GetValue<int>(); //or
e.GetIntValue();

答案 5 :(得分:1)

System.Enum投射到int对我来说很好(它也在MSDN上)。也许这是一个Resharper bug。

答案 6 :(得分:0)

由于枚举仅限于byte,sbyte,short,ushort,int,uint,long和ulong,我们可以做出一些假设。

我们可以通过使用最大的可用容器来避免转换期间的异常。不幸的是,使用哪个容器并不清楚,因为ulong会因为负数而爆炸,而long会在long.MaxValue和ulong.MaxValue之间爆炸。我们需要根据基础类型在这些选择之间切换。

当然,当结果不适合int时,你仍然需要决定该怎么做。我认为施法是可以的,但仍有一些问题:

  1. 对于基于字段空间大于int(long和ulong)的类型的枚举,可能某些枚举将评估为相同的值。
  2. 如果你在一个选中的区域,那么输出一个大于int.MaxValue的数字会抛出异常。
  3. 这是我的建议,我会留给读者决定在哪里公开这个功能;作为帮助者或延伸者。

    public int ToInt(Enum e)
    {
      unchecked
      {
        if (e.GetTypeCode() == TypeCode.UInt64)
          return (int)Convert.ToUInt64(e);
        else
          return (int)Convert.ToInt64(e);
      }
    }
    

答案 7 :(得分:0)

如果您阅读 Convert.ToInt32 的代码,您可以看到它将 Enum 强制转换为 IConvertible,然后调用 ToInt32(null)

答案 8 :(得分:-1)

不要忘记Enum类型本身有一堆静态辅助函数。如果您只想将枚举的实例转换为相应的整数类型,那么转换可能是最有效的方式。

我认为ReSharper抱怨是因为Enum不是任何特定类型的枚举,枚举本身来自标量值类型,而不是枚举。如果你需要以通用方式进行自适应投射,我会说这可以很好地适应你(请注意,枚举类型本身也包含在通用中:

public static EnumHelpers
{
    public static T Convert<T, E>(E enumValue)
    {
        return (T)enumValue;
    }
}

然后可以这样使用:

public enum StopLight: int
{
    Red = 1,
    Yellow = 2,
    Green = 3
}

// ...

int myStoplightColor = EnumHelpers.Convert<int, StopLight>(StopLight.Red);

我不能肯定地说,但上面的代码甚至可能得到C#的类型推断支持,允许以下内容:

int myStoplightColor = EnumHelpers.Convert<int>(StopLight.Red);