将枚举转换为无符号整数(uint)

9
我正在编写一个函数,该函数将Enum转换为uint。从我所见到的情况来看,当进行int类型转换时,您必须先将其转换为对象:(int) (object) myEnumValue。如果您直接写(int) myEnumValue,则会出现编译时异常。
现在,当我尝试将其转换为uint时,我期望(uint) (object) myEnumValue是正确的。它可以很好地编译,但运行时会生成InvalidCastException。因此,为了使其正常工作,我使用了
(uint) (int) (object) myEnumValue

我认为这看起来很有趣,所以我非常高兴,但为什么会这样呢?

也许更正确的做法是问为什么无法将 object 强制转换为 uint,但我想知道是否有其他方法从一个 Enum 转换为 uint。有吗?

编辑:

背景是一个函数,类似于这样:

public static uint ToUInt (Enum e)
{
    return (uint) (int) (object) e;
}
编辑2:

最佳解决方案如thecoop所述:

Convert.ToUInt32(e)
3个回答

16
(uint) (object) myEnum 的方法失败了,因为C#枚举默认将int作为其基础类型,在装箱时它们会转换为int。C#的语法使其看起来像是枚举从其基础类型继承(例如enum MyEnum : uint)。
你必须显式告诉编译器先从object拆箱为int,然后进行从intuint的数值转换。(即使语法相同,从object到值类型的拆箱过程与在intuint之间进行强制转换是不同的过程。)

好的,如果我将我的枚举指定为“Enum : uint”,那么它会反过来吗? - Jonatan Lindén
@Jonatan:是的,这将把枚举封装为uint,并强制您将其解封为uint。 - R. Martinho Fernandes
没错:(uint) e 没问题,但 (int) e 会出问题。 - Tim Robinson
1
@Tim:继承是一个错误的术语。你不能从 System.Int32 继承(也许你可以用一些巫术黑魔法,但那不是相关的)。枚举从 System.Enum 继承。正确的说法是底层类型是 int - R. Martinho Fernandes
嗯,你说得对。在这种情况下,重要的是将枚举装箱为整数。 - Tim Robinson
@thecoop,是的,如果你不确定你正在处理一个int还是uint,这可能是唯一实用的方法。添加你自己的答案,我会给你点赞 :) - Tim Robinson

6
据我所见,将枚举类型转换为整数时,您必须首先将其转换为对象:(int) (object) myEnum。如果您写(int) myEnum,则会在编译时出现异常。
不是这样的。您可以直接将枚举值强制转换为整数类型。
现在,当我尝试将其转换为uint时,我期望(uint) (object) myEnum应该没问题。它可以编译通过,但在运行时,它会生成InvalidCastException。因此,为了使它正常工作,我使用了:(uint) (int) (object) myEnum。我觉得它看起来很有趣,所以我很高兴,但为什么要这样呢?
当您将枚举值强制转换为object时,它将作为其默认的“基础类型”装箱为int。您无法直接将装箱值解箱到除其实际类型以外的任何类型。即使这样也会失败:
short s = 10;
object o = s;
int i = (int)o; // throws `InvalidCastException` while `int i = (int)s;` works.

1

如果您需要进行相反的操作,即从基础类型转换为特定类型的枚举:

enum MyEnumType { a, b, c };
//...
MyEnumType enum_val = (MyEnumType)Enum.ToObject(typeof(MyEnumType), 2);
Console.WriteLine(enum_val == MyEnumType.c);
// "True"

我发现在编写泛型类型时,这比简单的转换更为必要。由于您无法使用“where”子句来充分约束泛型<T>到枚举类型,因此编译器不会让您将数字转换为它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接