我一直在对此进行试验,使用 ILSpy 来检查输出,这就是我发现的。
显然,在您的第二种情况下,这是一个错误-您无法比较 aulong
和 anint
因为没有可以强制两者的类型。Aulong
可能对于 a 来说太大了long
,并且 anint
可能是负数。
但是,在您的第一种情况下,编译器很聪明。它意识到 const 1
> const32
永远不是真的,并且根本不将您的if
语句包含在编译输出中。(它应该对无法访问的代码发出警告。)如果您定义和使用 aconst int
而不是文字,或者即使您明确地转换文字(即(int)32
),也是一样的。
但是编译器不是成功地将 aulong
与a 进行比较int
,我们刚才说这是不可能的吗?
显然不是。那么这是怎么回事?
尝试按照以下方式做一些事情。(接受输入并写入输出,因此编译器不会编译任何东西。)
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
视为ulong
. 如果你 make thirtytwo = -1
,代码将无法编译,即使我们知道这gt
将永远是正确的。编译器本身无法将 aulong
与 a 进行比较int
。
另请注意,如果您使用x
along
而不是 a ulong
,编译器会生成32L
而不是32
整数,即使它不是必须的。(您可以在运行时比较 anint
和 a long
。)
这表明编译器在第一种情况下没有将32
其视为 a ,因为它必须这样做,仅仅是因为它可以匹配 的类型。它使运行时不必强制常量,这只是当强制应该不可能的时候的奖励。ulong
x