Ответ 1
Компилятор игнорирует левую сторону при определении типа правой части. Поэтому, когда он пытается вывести тип
Int64.Parse(myOtherVar) == 0 ? null : Int64.Parse(myOtherVar)
он делает это, не обращая внимания на то, что левая часть a long?
. Чтобы определить тип правой части, он отмечает, что
Int64.Parse(myOtherVar)
является long
и теперь пытается увидеть, является ли null
или неявно преобразован в long
. Поскольку он не может, вы получите сообщение об ошибке, которое вы видите.
Из раздела 7.14 спецификации С#:
Условное выражение формы
b ? x : y
....Второй и третий операнды
x
иy
оператора?:
управляют типом условного выражения.(1) Если
x
имеет типx
иy
имеет типy
, тоа. Если неявное преобразование (§6.1) существует от
x
доy
, но не отy
доx
, тоy
является типом условного выражения.б. Если неявное преобразование (§6.1) существует от
y
доx
, но не отx
доy
, тоx
является типом условного выражения.с. В противном случае тип выражения не может быть определен, и возникает ошибка времени компиляции.
(2) Если только один из
x
иy
имеет тип, и обаx
иy
, из которых неявно конвертируются в этот тип, то это тип условного выражения.(3) В противном случае тип выражения не может быть определен, и возникает ошибка времени компиляции.
Обратите внимание, что мы находимся в ситуации (2), где x
есть null
и не имеет типа, а y
- Int64.Parse(myOtherVar)
и имеет тип long
. Обратите внимание, что x
неявно конвертируется в тип y
. Поэтому и (1), и (2) терпят неудачу выше, и мы приводим к (3), что приводит к ошибке времени компиляции, которая вдохновила ваш вопрос. Обратите внимание на неявный вывод из сказанного выше, что левая часть не играет роли в определении типа правой части.
Чтобы исправить это, замените
Int64.Parse(myOtherVar)
с
(long?)Int64.Parse(myOtherVar)
Теперь, почему
myVar = null;
в порядке, где myVar
объявлен как long?
, потому что компилятор знает, что существует неявное преобразование от null
до long?
.
Наконец, Int64.Parse
будет бросать, если myOtherVar
не может быть проанализирован на long
. Обратите внимание, что вы также выполняете синтаксический анализ дважды, что необязательно. Лучшая модель
long value;
if(Int64.TryParse(myOtherVar, out value)) {
myVar = value == 0 ? null : (long?)value;
}
else {
// handle case where myOtherVar couldn't be parsed
}