Подтвердить что ты не робот

Почему это неявное преобразование из int в uint работает?

Использование Кастинг null не компилирует как вдохновение, а из комментария Эрика Липперта:

Это демонстрирует интересный случай. "uint x = (int) 0;" бы хотя int неявно конвертируется в uint.

Мы знаем, что это не работает, потому что object нельзя назначить string:

string x = (object)null;

Но это так, хотя интуитивно это не должно:

uint x = (int)0;

Почему делает компилятор разрешает этот случай, когда int неявно конвертируется в uint?

4b9b3361

Ответ 1

Целочисленные константные преобразования рассматриваются как особо специальные языком С#; здесь раздел 6.1.9 спецификации:

Постоянное выражение типа int может быть преобразовано в тип sbyte, byte, short, ushort, uint или ulong, если значение константного выражения находится в пределах диапазона типа назначения. Постоянное выражение типа long может быть преобразовано в тип ulong, если значение константного выражения не является отрицательным.

Это позволяет вам делать такие вещи, как:

byte x = 64;

который в противном случае потребовал бы уродливого явного преобразования:

byte x = (byte)64; // gross

Ответ 2

Следующий код wil завершится неудачей с сообщением "Невозможно неявно преобразовать тип" int "в" uint ". Явное преобразование существует (вы пропускаете листинг?)"

int y = 0;
uint x = (int)y;

И это не сработает с: "Постоянное значение" -1 "не может быть преобразовано в" uint "

uint x = (int)-1;

Таким образом, единственная причина uint x = (int)0; заключается в том, что компилятор видит, что 0 (или любое другое значение > 0) является константой времени компиляции, которая может быть преобразована в uint

Ответ 3

В целом компиляторы имеют 4 шага, в которых код преобразуется. Текст символизирован > Анализируются токены > Создается AST + ссылкa > AST преобразуется в целевой язык.

Оценка констант, таких как числа и строки, происходит как первый шаг, и компилятор, вероятно, рассматривает 0 как действительный токен и игнорирует листинг.