ILSpyを使用して出力を調べてこれを実験してきましたが、これが私が発見したものです。
明らかに、2番目のケースでは、これはエラーです。両方を強制できるタイプがないため、ulong
とを比較することはできません。int
Aulong
は、に対して大きすぎる可能性がlong
あり、int
は負の可能性があります。
ただし、最初のケースでは、コンパイラーは巧妙です。1
const > 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
であることがわかっていても、コードのコンパイルに失敗します。コンパイラ自体は、をと比較することはできません。gt
ulong
int
また、の代わりにを作成するx
と、コンパイラは整数ではなく生成しますが、整数として生成する必要はありません。(実行時にとを比較できます。)long
ulong
32L
32
int
long
これは、コンパイラが最初のケースで32
として扱わないことを示しています。これは、コンパイラが。のタイプと一致する可能性があるという理由だけで、そうしなければならないためです。これにより、ランタイムが定数を強制する必要がなくなります。これは、権利によって強制が不可能な場合の単なるボーナスです。ulong
x