Оператор нуль-коалесценции - зачем кастинг?

Может кто-нибудь сказать, пожалуйста, почему первое из следующих утверждений выдает ошибку компиляции, а второе - нет?

NewDatabase.AddInParameter(NewCommand, "@SomeString", DbType.String, SomeString ?? DBNull.Value); // <-- Throws compilation error!
NewDatabase.AddInParameter(NewCommand, "@SomeString", DbType.String, (object)(SomeString) ?? DBNull.Value); // <-- Compiles!

Я пробовал другие обнуляемые типы, такие как byte? и получил тот же результат. Может ли кто-нибудь сказать мне, почему мне нужно сначала привести объект к объекту?

5 ответов

Решение

Вы должны указать компилятору, какой тип использовать. Тип результата оператора слияния null должен совпадать с типом операнда (или базовым типом первого операнда, если в некоторых случаях это тип значения, допускающий значение NULL). Он не пытается найти "наиболее специфический тип, в который могут быть преобразованы оба операнда", или что-то подобное.

Подробнее о том, как определяется язык, когда дело доходит до оператора объединения нулей, см. Спецификацию языка C# 4, раздел 7.13:

Тип выражения a ?? b зависит от того, какие неявные преобразования доступны для операндов. В порядке предпочтения тип a ?? b является A0, A, или же B, где A это тип a (при условии, что a имеет тип), B это тип b (при условии, что b имеет тип), и A0 это основной тип A если A обнуляемый тип, или A иначе.

Первый пример терпит неудачу, потому что SomeString а также DBValue.Null не являются неявно взаимозаменяемыми типами.

Это связано с тем, что тип в правой части оператора слияния нуля должен быть неявно преобразован в тип в левой части (или наоборот). Для вашего первого примера задействованы следующие типы: string а также DBNull, Эти типы не связаны, поэтому преобразование не выполняется.

Потому что выражение должно иметь один тип возвращаемого значения. поскольку String а также DbValue не может быть приведен друг к другу, компилятор не может определить, какой тип возврата вы хотите. Когда вы приводите к Object, вы предоставляете компилятору тип, на который он может привести.

DBValue.Null не является строкой; это объект..NET не будет неявно приведен к Object в выражениях; должно быть явно сказано, что вы ожидаете результата Object.

Другие вопросы по тегам