Спецификация (§7.14) гласит, что для условного выражения b ? x : yсуществует три возможности, xи yоба имеют тип и выполняются определенные хорошие условия , только один из xи yимеет тип, и определенные хорошие условия выполняются, или ошибка времени компиляции происходит. Здесь «определенные хорошие условия» означают, что возможны определенные преобразования, о которых мы поговорим ниже.
Теперь давайте обратимся к немецкой части спецификации:
Если только один из xи yимеет тип, и оба, xи yнеявно преобразуются в этот тип, то это тип условного выражения.
Проблема здесь в том, что в
int? number =true?5:null;
только один из условных результатов имеет тип. Вот xэто intбуквально, и yэто nullкоторый не не имеют типа и nullне неявно раскладывается в int1 . Следовательно, «определенные хорошие условия» не выполняются, и возникает ошибка времени компиляции.
Там являются два пути вокруг этого:
int? number =true?(int?)5:null;
Здесь мы все еще в случае, когда только один из xи yимеет тип. Обратите внимание , что до nullсих пор не имеет типа пока компилятор не будет иметь никаких проблем с этим , потому что (int?)5и nullоба неявно преобразованы в int?(§6.1.4 и §6.1.5).
Другой способ, очевидно,
int? number =true?5:(int?)null;
но теперь мы должны прочитать другой пункт в спецификации, чтобы понять, почему это нормально:
Если xимеет тип Xи yимеет тип, Yто
Если неявное преобразование (§6.1) существует из Xto Y, но не из Yto X, тогда Yэто тип условного выражения.
Если неявное преобразование (§6.1) существует из Yto X, но не из Xto Y, тогда Xэто тип условного выражения.
В противном случае тип выражения не может быть определен, и возникает ошибка времени компиляции.
Вот xтипа intи yтипа int?. Там нет неявного преобразования int?к int, но есть неявное преобразование intк int?такому типу выражения int?.
1 : Отметим далее, что тип левой части игнорируется при определении типа условного выражения, что является распространенным источником путаницы.
Хорошая цитата из спецификации, чтобы проиллюстрировать, почему это происходит - +1!
JerKimball
8
Другой вариант new int?()на месте (int?)null.
Гуванте
1
Это также относится к случаю, если у вас есть тип поля базы данных, обнуляемый обнуляемым значением, например, обнуляемый тип DateTime, и вы пытаетесь привести данные к ним DateTime, когда это потребуется,(DateTime?)
Майк Апджон,
73
null не имеет идентифицируемого типа - просто нужно немного подтолкнуть его, чтобы сделать его счастливым:
Проблема не в том, nullчто не имеет идентифицируемого типа. Проблема в том, что нет неявного преобразования из nullв int. Подробности здесь .
Джейсон
Интересно то, что int? number = true ? 5 : (int?)null;и int? number = true ? (int?)5 : null;как компиляции !! Царапина, царапина
davidhq
2
Я объясняю точно, почему это происходит в моем ответе .
Джейсон
4
Как уже упоминали другие, 5 является int, и nullне может быть неявно преобразовано в int.
Вот другие способы обойти эту проблему:
int? num =true?5:default(int?);int? num =true?5:newint?();int? num =true?5:nullasint?;int? num =true?5:(int?)null;int? num =true?(int?)5:null;int? num =true?5asint?:null;int? num =true?newint?(5):null;
Кроме того, везде, где вы видите int?, вы также можете использовать Nullable<int>.
Иногда условно и?: выражения не имеют очевидного общего типа между ветвями. Такие случаи сегодня терпят неудачу, но C # 9.0 разрешит их, если есть целевой тип, в который преобразуются обе ветви:
Person person = student ?? customer;// Shared base typeint? result = b ?0:null;// nullable value type
Ответы:
Спецификация (§7.14) гласит, что для условного выражения
b ? x : y
существует три возможности,x
иy
оба имеют тип и выполняются определенные хорошие условия , только один изx
иy
имеет тип, и определенные хорошие условия выполняются, или ошибка времени компиляции происходит. Здесь «определенные хорошие условия» означают, что возможны определенные преобразования, о которых мы поговорим ниже.Теперь давайте обратимся к немецкой части спецификации:
Проблема здесь в том, что в
только один из условных результатов имеет тип. Вот
x
этоint
буквально, иy
этоnull
который не не имеют типа иnull
не неявно раскладывается вint
1 . Следовательно, «определенные хорошие условия» не выполняются, и возникает ошибка времени компиляции.Там являются два пути вокруг этого:
Здесь мы все еще в случае, когда только один из
x
иy
имеет тип. Обратите внимание , что доnull
сих пор не имеет типа пока компилятор не будет иметь никаких проблем с этим , потому что(int?)5
иnull
оба неявно преобразованы вint?
(§6.1.4 и §6.1.5).Другой способ, очевидно,
но теперь мы должны прочитать другой пункт в спецификации, чтобы понять, почему это нормально:
Вот
x
типаint
иy
типаint?
. Там нет неявного преобразованияint?
кint
, но есть неявное преобразованиеint
кint?
такому типу выраженияint?
.1 : Отметим далее, что тип левой части игнорируется при определении типа условного выражения, что является распространенным источником путаницы.
источник
new int?()
на месте(int?)null
.DateTime
, когда это потребуется,(DateTime?)
null
не имеет идентифицируемого типа - просто нужно немного подтолкнуть его, чтобы сделать его счастливым:источник
int? number = true ? 5 : null as int?;
null
что не имеет идентифицируемого типа. Проблема в том, что нет неявного преобразования изnull
вint
. Подробности здесь .int? number = true ? 5 : (int?)null;
иint? number = true ? (int?)5 : null;
как компиляции !! Царапина, царапинаКак уже упоминали другие, 5 является
int
, иnull
не может быть неявно преобразовано вint
.Вот другие способы обойти эту проблему:
Кроме того, везде, где вы видите
int?
, вы также можете использоватьNullable<int>
.источник
В
C# 9
этом сейчас разрешен блогИли ваш пример:
источник