我一直在对此进行试验,使用 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。
另请注意,如果您使用xalong而不是 a ulong,编译器会生成32L而不是32整数,即使它不是必须的。(您可以在运行时比较 anint和 a long。)
这表明编译器在第一种情况下没有将32其视为 a ,因为它必须这样做,仅仅是因为它可以匹配 的类型。它使运行时不必强制常量,这只是当强制应该不可能的时候的奖励。ulongx