Почему я не могу использовать операнд '??' для System.Значение DBNull?
Вопрос
У меня есть таблица данных Oracle, извлекающая столбцы, которые имеют значение null.Итак, я полагаю, что для того, чтобы сохранить код красивым и простым, я бы использовал ??операнд.AlternatePhoneNumber - это строка в моей модели C#.
AlternatePhoneNumber = customer.AlternatePhoneNumber ?? ""
Однако даже с этим кодом я все равно получаю сообщение об ошибке.
System.InvalidCastException: Unable to cast object of type 'System.DBNull' to type 'System.String'.
Я знаю, что означает эта ошибка, но почему??не используется в DBNull?Разве null и DBNull по сути не одно и то же?
Спасибо тебе.
Решение
То ??
оператор применяется только к фактическим null
s.
null
и DBNull.Value
это не одно и то же; DBNull.Value
это просто объект-заполнитель.
Кроме того, это исключение исходит изнутри AlternatePhoneNumber
собственность, прежде чем ваш ??
оператор выполняет.(В вашем коде нет приведения).
Если customer
является строкой в типизированном наборе данных, измените значение столбца NullValue
недвижимость в дизайнерском исполнении.
Другие советы
null и dbnull не одинаковы.System.dbnull - это фактический объект.
Проблема в том, что AlternatePhoneNumber
это строка.DBNull - это не так.
Попробуйте это вместо этого:
AlternatePhoneNumber = (customer.AlternatePhoneNumber as string) ?? ""
Делай это:
public T IfNull<T>(object o, T value)
{
return (o == DbNull.Value) ? value : (T)o;
}
. DBNull - это тип с одним значением, и это не то же самое, что ссылка на строку null, поэтому вы не можете использовать ??
.Однако вы могли бы сделать это:
string alternativePhoneNumber = DBNull.Value.Equals(customer) ? string.Empty : ((Customer)customer).AlternatePhoneNumber;
Как указано в других ответах, null
означает ссылку, которая не ссылается ни на один объект, в то время как DBNull
является классом, предоставляемым ADO.NET для указывать когда поле или значение равно NULL в базе данных (или в DataTable).
В то время как вы можете использовать условный (троичный) оператор (?:) делать то, что ты хочешь:
AlternatePhoneNumber = customer.AlternatePhoneNumber is DBNull
? ""
: customer.AlternatePhoneNumber;
Я склонен обобщать это в способ расширения:
static class NullExtensions
{
public static T WhenNull<T>( this object value, T whenNullValue )
{
return (value == null || value is DBNull)
? whenNullValue
: (T)value;
}
}
что, как я нахожу, облегчает чтение и понимание кода.
AlternatePhoneNumber = customer.AlternatePhoneNumber.WhenNull( "" );
Добулл не настоящий "нулевой".
"??"- Оператор обнаруживает только NULL - ссылки, а не объекты, которые эмулируют «нулевое» поведение.