Ответ 1
Я экспериментировал с этим, используя ILSpy для изучения вывода, и это то, что я обнаружил.
Очевидно, что в вашем втором случае это ошибка - вы не можете сравнить ulong
и int
, потому что не существует типа, с которым вы можете принуждать обоих. A ulong
может быть слишком большим для long
, а int
может быть отрицательным.
В вашем первом случае, однако, компилятор умный. Он понимает, что const 1
> const 32
никогда не является истинным и не включает ваш оператор 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
всегда будет true. Сам компилятор не может сравнивать ulong
с int
.
Также обратите внимание, что если вы создаете x
a long
вместо ulong
, компилятор генерирует 32L
, а не 32
как целое число, даже если это не обязательно. (Вы можете сравнить int
и a long
во время выполнения.)
Это указывает на то, что компилятор не обрабатывает 32
как ulong
в первом случае, потому что он должен, просто потому, что он может соответствовать типу x
. Это экономит время выполнения от принуждения константы, и это просто бонус, когда принуждение по правам не может быть возможным.