Унарный минус на коротком становится int? - PullRequest
8 голосов
/ 13 января 2010

В следующем:

public class p
{
  short? mID;
  short? dID;
}

short id = p.mID ?? -p.dID.Value;

Компилятор выдает ошибку:

Ошибка 21 Не удается неявно преобразовать тип 'int' в 'short'. Существует явное преобразование (вам не хватает приведения?)

Я должен изменить код на следующий, чтобы он работал:

short id = p.mID ?? (short)-p.dID.Value;

Это как если бы компилятор делал что-то вроде (int) 0 - p.dID.Value или что Int16.operator - возвращал Int32s ...

Ответы [ 2 ]

13 голосов
/ 13 января 2010

Я отсылаю вас к разделу 7.6.2 спецификации, в котором говорится:


Для операции вида –x применяется разрешение перегрузки унарного оператора для выбора конкретной реализации оператора. Операнд преобразуется в тип параметра выбранного оператора, а тип результата является типом возврата оператора. Предопределенные операторы отрицания:

Целочисленное отрицание:

int operator –(int x);
long operator –(long x);

Результат вычисляется путем вычитания x из нуля. Если значение x является наименьшим представимым значением типа операнда (−2 ^ 31 для int или −2 ^ 63 для long), то математическое отрицание x не представимо в типе операнда. Если это происходит в проверенном контексте, выдается исключение System.OverflowException; если это происходит в неконтролируемом контексте, результатом является значение операнда, а переполнение не сообщается. Если операнд оператора отрицания имеет тип uint, он преобразуется в тип long, а тип результата - long. Исключением является правило, позволяющее записать значение int -2147483648 (-2 ^ 31) в виде десятичного целочисленного литерала.

Если операнд оператора отрицания имеет тип ulong, возникает ошибка времени компиляции. Исключением является правило, позволяющее записывать длинное значение -9223372036854775808 (-2 ^ 63) в виде десятичного целочисленного литерала.

Отрицание с плавающей точкой:

float operator –(float x);
double operator –(double x);

Результатом является значение x с инвертированным знаком. Если x равен NaN, результат также равен NaN.

Десятичное отрицание:

decimal operator –(decimal x);

Результат вычисляется путем вычитания x из нуля. Десятичное отрицание эквивалентно использованию унарного минусового оператора типа System.Decimal.


Как видите, в шортах не определен унарный оператор минус; разрешение перегрузки выбирает единицу для целочисленных значений, поскольку это наилучшее совпадение среди всех доступных унарных минус операторов.

2 голосов
/ 13 января 2010

Нет унарного минусового оператора, который принимает короткое значение. Вместо этого разрешение перегрузки выбирает версию int унарного оператора минус и выполняет неявное преобразование.

...