2015-09-30 9 views
7

Есть ли причина, по которой я не могу использовать следующий код?return ulong in inline-if

ulong test(int a, int b) 
{ 
    return a == b ? 0 : 1; 
} 

Он показывает мне:

Cannot implicitly convert type 'int' to 'ulong'. An explicit conversion exists (are you missing a cast?) 

Ниже будет работать:

ulong test(int a, int b) 
{ 
    return false ? 0 : 1; 
} 

Я знаю, как решить эту проблему. Я просто хочу знать причину.

Спасибо.

+0

В последнем блоке кода он работает, если вы замените 'false' на' true'? Может быть, есть какая-то причина, что '1' может быть неявно преобразован на' 0', не может? –

+0

Уже протестировано, это не имеет значения. –

+6

Это 'false? 0: 1' является постоянным выражением. Это 'return a == b? 0: 1' нет. Постоянное выражение типа 'int' разрешено преобразовывать неявно в' ulong', если оно соответствует диапазону 'ulong'. – PetSerAl

ответ

5

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

IL_0000: nop 
IL_0001: ldc.i4.1 
IL_0002: conv.i8 
IL_0003: stloc.0 
IL_0004: br.s  IL_0006 
IL_0006: ldloc.0 
IL_0007: ret 

На IL_0001 буквальным 1 помещается в стек (так что выражение return false ? 0 : 1; вычисляется на этапе компиляции и встраивается в IL как константа), и в IL_0002 этот литерал преобразуется в Int64.

Из MSDN:

Константа-выражение (раздел 7.15) типа Int может быть преобразован в типа SByte, байт, короткие, USHORT, UINT или ULONG, при условии, что значение из константа -expression находится в пределах диапазона типа назначения.

Поскольку 1 находится в диапазоне от типа ulong данных, такое преобразование всегда будет успешным. Компилятор знает это и поэтому выполняет неявное преобразование.

0

Это будет работать:

ulong test(int a, int b) 
{ 
    return a == b ? 0UL : 1UL; 
} 

Престол, компилятор выводит тип от размера номера, так что если вы хотите определенного типа, вы должны дать суффикс. См. Раздел «Литералы» об этом MSDN page

Редактировать: Как указывалось на мне, этот вопрос не искал ответа о том, как заставить его работать. Я считаю, что в статье MSDN все еще есть какая-то ценность. Он предоставляет информацию, которая может объяснить, почему неудачный случай не работает, но не о том, почему другой проходит. Действительно интересная проблема.

+2

Вопрос не в том, как заставить его работать, он спрашивает, почему второй случай работает, когда первый не работает. – juharr

+0

@juharr Так оно и есть. Добираемся до конца дня, и мой мозг жарится здесь. Хотя часть литералов по-прежнему применяется правильно? Это объясняет, почему это не работает, но не почему это делает второй случай. –

2

Переменные, введенные как int, не могут быть неявно преобразованы в ulong, поскольку int может представлять отрицательное значение, в то время как ulong не может. Постоянная может быть неявно преобразована при условии, что значение константного выражения неотрицательно.

Ваш второй пример - это постоянное выражение.