【发布时间】:2018-03-21 18:21:08
【问题描述】:
在使用具有多个重载的外部 API 时,这些重载采用不同的数据类型但没有枚举,我决定创建一个方便的方法来为枚举提供更多的类型安全性,并最终得到这样的结果:
namespace TestEnumPromotion
{
enum Values
{
Value0,
Value1,
}
class Program
{
static void Main(string[] args)
{
// Prints int
Overloaded(0);
// Prints Values
Overloaded(Values.Value0);
// Does not compile! :-/
Overloaded((byte) 0);
// Prints int
byte b = 0;
Overloaded(b);
}
static void Overloaded(int i)
{
Console.WriteLine("int");
}
static void Overloaded(Values i)
{
Console.WriteLine("Values");
}
}
}
但我很惊讶地看到代码没有编译,因为Overloaded((byte) 0):
以下方法或属性之间的调用不明确:“Program.Overloaded(int)”和“Program.Overloaded(Values)”
但是byte不能自动提升为Values,也就是说Values v = (byte)b不会编译,因为:
无法将类型“字节”隐式转换为“TestEnumPromotion.Values”。
所以唯一可能的重载应该是 int,对吧?
我认为枚举可能只是语法糖,编译器会生成接收 int 的方法,但通过 ILDASM 查看 IL 表明实际上创建了一个采用枚举的方法。
.method private hidebysig static void Overloaded(valuetype TestEnumPromotion.Values i) cil managed
{
// Code size 13 (0xd)
.maxstack 8
IL_0000: nop
IL_0001: ldstr "Values"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: ret
} // end of method Program::Overloaded
发生了什么?
【问题讨论】:
-
你可以声明基于其他数值类型的枚举(例如
enum Values : long),但默认是int。