Почему я не могу использовать «??» операнд для значения System.DBNull? - PullRequest
3 голосов
/ 09 июля 2010

У меня есть таблица данных Oracle для выборки столбцов, которые имеют нулевое значение.Так что я решил сохранить код красивым и простым, чтобы я использовал ??операнд.AlternatePhoneNumber - это строка в моей модели C #.

AlternatePhoneNumber = customer.AlternatePhoneNumber ?? ""

Однако даже с этим кодом я все еще получаю сообщение об ошибке.

System.InvalidCastException: Unable to cast object of type 'System.DBNull' to type 'System.String'.

Я знаю, что означает ошибка, но почему?нельзя использовать на DBNull?Разве null и DBNull по сути не совпадают?

Спасибо.

Ответы [ 7 ]

15 голосов
/ 09 июля 2010

Оператор ?? применяется только к фактическим null с.

null и DBNull.Value не совпадают;DBNull.Value - это просто объект-заполнитель.

Кроме того, это исключение поступает из свойства AlternatePhoneNumber до выполнения оператора ??.(Ваш код не имеет приведения).

Если customer - строка в наборе типизированных данных, измените свойство столбца NullValue в конструкторе.

3 голосов
/ 09 июля 2010

Проблема в том, что AlternatePhoneNumber является строкой.DBNull не является.

Попробуйте вместо этого:

AlternatePhoneNumber = (customer.AlternatePhoneNumber as string) ?? ""
3 голосов
/ 09 июля 2010

null и DBNull не совпадают. System.DBNull - это реальный объект.

2 голосов
/ 09 июля 2010

Сделайте это:

public T IfNull<T>(object o, T value)
{
   return (o == DbNull.Value) ? value : (T)o;       
}
2 голосов
/ 09 июля 2010

DBNull - это тип с одним значением, который не совпадает с пустой строкой, поэтому вы не можете использовать ??.Вы можете сделать это, однако:

string alternativePhoneNumber = DBNull.Value.Equals(customer) ? string.Empty : ((Customer)customer).AlternatePhoneNumber;
1 голос
/ 09 июля 2010

DBNull НЕ является настоящим "нулем".

"??" - оператор обнаруживает только нулевые ссылки, а не объекты, имитирующие «нулевое» поведение.

1 голос
/ 09 июля 2010

Как и в других состояниях ответов, 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( "" );
...