编辑:底部的评论。另外,这.
这就是让我感到困惑的地方。我的理解是,如果我有这样的枚举......
enum Animal
{
Dog,
Cat
}
...我基本上所做的是定义了一个用两个定义的值调用的值类型,并且. 此类型派生自引用类型(值类型通常不能做的事情——至少在 C# 中是不允许的——但在这种情况下是允许的),并且具有来回转换到值/从值转换的功能。Animal
Dog
Cat
System.Enum
int
如果我刚才描述的枚举类型是真的,那么我希望下面的代码会抛出一个InvalidCastException
:
public class Program
{
public static void Main(string[] args)
{
// Box it.
object animal = Animal.Dog;
// Unbox it. How are these both successful?
int i = (int)animal;
Enum e = (Enum)animal;
// Prints "0".
Console.WriteLine(i);
// Prints "Dog".
Console.WriteLine(e);
}
}
通常,您不能将值类型从System.Object
它的确切类型以外的任何东西拆箱。那么以上怎么可能呢?就好像该Animal
类型同时是一个int
(不仅仅是可转换为int
)并且是(Enum
不仅仅是可转换为Enum
)。是多重继承吗?是否System.Enum
以某种方式继承自System.Int32
(我没想到会发生的事情)?
编辑:它不能是上述任何一个。以下代码最终证明了这一点(我认为):
object animal = Animal.Dog;
Console.WriteLine(animal is Enum);
Console.WriteLine(animal is int);
上述输出:
真的 错误的
MSDN 关于枚举的文档和 C# 规范都使用了术语“底层类型”;但我不知道这是什么意思,我也从未听说过它用于指代枚举以外的任何东西。“基础类型”实际上是什么意思?
那么,这是否是另一个从 CLR 获得特殊处理的案例?
我的钱是在这种情况下......但答案/解释会很好。
更新:Damien_The_Unbeliever提供了真正回答这个问题的参考。可以在 CLI 规范的第 II 部分中的枚举部分中找到解释:
出于绑定目的(例如,从用于调用它的方法引用中定位方法定义),枚举应与它们的底层类型不同。对于所有其他目的,包括验证和执行代码,未装箱的枚举可以自由地与其基础类型相互转换。枚举可以被装箱到对应的装箱实例类型,但是这种类型和底层类型的装箱类型不一样,所以装箱不会丢失枚举的原始类型。
编辑(再次?!):等等,实际上,我不知道我第一次读对了。也许它并不能 100% 解释专门的拆箱行为本身(尽管我将 Damien 的回答视为已接受,因为它对这个问题有很大的了解)。我会继续研究这个...
另一个编辑:伙计,然后yodaj007 的回答让我陷入了另一个循环。不知何故,枚举与 ; 并不完全相同int
。仍然int
可以将 an 分配给没有强制转换的枚举变量吗?嗯?
我认为这一切最终都被汉斯的回答所阐明,这就是我接受它的原因。(对不起,达米安!)