ILSpyを使用して出力を調べてこれを実験してきましたが、これが私が発見したものです。
明らかに、2番目のケースでは、これはエラーです。両方を強制できるタイプがないため、ulongとを比較することはできません。intAulongは、に対して大きすぎる可能性がlongあり、intは負の可能性があります。
ただし、最初のケースでは、コンパイラーは巧妙です。1const > const32は決して真ではなくif、コンパイルされた出力にステートメントがまったく含まれていないことを認識しています。(到達不能コードに対して警告を出す必要があります。)const intリテラルではなくを定義して使用する場合、またはリテラルを明示的にキャストする場合でも同じです(つまり(int)32)。
しかし、コンパイラーは、先ほど不可能だと言っulongた、とを正常に比較していませんか?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。を作成すると、それが常に真thirtytwo = -1であることがわかっていても、コードのコンパイルに失敗します。コンパイラ自体は、をと比較することはできません。gtulongint
また、の代わりにを作成するxと、コンパイラは整数ではなく生成しますが、整数として生成する必要はありません。(実行時にとを比較できます。)longulong32L32intlong
これは、コンパイラが最初のケースで32として扱わないことを示しています。これは、コンパイラが。のタイプと一致する可能性があるという理由だけで、そうしなければならないためです。これにより、ランタイムが定数を強制する必要がなくなります。これは、権利によって強制が不可能な場合の単なるボーナスです。ulongx