Невозможное сравнение улонга и лонга вдруг стало возможным


Я знаю, почему это запрещено:

ulong x = 0xFEDCBA9876543210;
long y = Int64.MaxValue;
Console.WriteLine(x < y);
Очевидно, что среда выполнения не может неявно привести операнд к другому типу или большему типу, чтобы сравнение работало.

Оператор '

Таким образом, это также не допускается (с MinValue и const):

ulong x = 0xFEDCBA9876543210;
const long y = Int64.MinValue;
Console.WriteLine(x < y);

Тем не менее, это разрешено (с MaxValue вместо этого):

ulong x = 0xFEDCBA9876543210;
const long y = Int64.MaxValue;
Console.WriteLine(x < y);

Не существует перегрузки <, принимающей a ulong и long, но я видел с рефлектором, что это безмолвно преобразует Int64.MaxValue в ulong. Но это происходит не всегда. Как это работает, и какие соображения являются причиной этого несоответствия?

2 6

2 ответа:

Одно большое различие между long y = Int64.MaxValue; if (x < y)... и if (x < Int64.MaxValue) состоит в том, что в последнем случае компилятор может фактически видеть постоянное значение, если он этого хочет. Он может видеть, что фактическое постоянное значение соответствует диапазону ulong, и поэтому неявное приведение в порядке.

Для простой переменной long y компилятор не может сделать никаких предположений о том, что такое значение времени выполнения Y. Неважно, что оператор присваивания является всего лишь одним оператором вверх; компилятор не отслеживает значения, присвоенные переменная.

Как отметил DarkGray, const var ведет себя как константа, так как вы сказали компилятору, что его значение никогда не изменится.

Const long со значением в диапазоне ulong молча преобразуется в const ulong.

Это разрешено:

ulong x = 0xFEDCBA9876543210; 
const long y = Int64.MaxValue; 
Console.WriteLine(x < y); 

const ulong z = y;