我一直在尝试这个,使用 ILSpy 检查输出,这就是我的发现。
显然,在你的第二种情况下,这是一个错误 - 你不能比较ulong
and an int
因为没有一种类型可以强制两者。 Aulong
对于一个来说可能太大了long
, 和int
可能是负数。
然而,在第一种情况下,编译器很聪明。它意识到const1
> 常量32
从来都不是真的,并且不包括你的if
编译输出中的语句根本没有。 (它应该对无法访问的代码发出警告。)如果您定义并使用const int
而不是文字,或者即使您显式地转换文字(即(int)32
).
但那不是compiler成功比较了ulong
与int
,我们刚才说这是不可能的?
显然不是。所以呢is发生什么事了?
尝试按照以下方式做一些事情。 (获取输入并写入输出,这样编译器就不会编译任何内容。)
const int thirtytwo = 32;
static void Main(string[] args)
{
ulong x = ulong.Parse(Console.ReadLine());
bool gt = x > thirtytwo;
Console.WriteLine(gt);
}
这将编译,即使ulong
是一个变量,即使结果在编译时未知。看一下 ILSpy 中的输出:
private static void Main(string[] args)
{
ulong x = ulong.Parse(Console.ReadLine());
bool gt = x > 32uL; /* Oh look, a ulong. */
Console.WriteLine(gt);
}
所以,编译器实际上正在处理你的const int
as a ulong
。如果你做thirtytwo = -1
,代码无法编译,即使我们知道gt
will always是真实的。编译器本身无法比较ulong
to an int
.
另请注意,如果您使x
a long
代替ulong
,编译器生成32L
而不是32
作为一个整数,即使它不是have到。 (您可以比较int
and a long
在运行时。)
这表明编译器不处理32
as a ulong
在第一种情况下,因为它has仅仅因为它can匹配类型x
。它使运行时不必强制强制常量,这只是当强制强制不可能时的一个好处。