为什么我不能用'??' System.DBNull值的操作数?

时间:2010-07-09 13:40:47

标签: c# oracle 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基本相同吗?

谢谢。

7 个答案:

答案 0 :(得分:15)

??运算符仅适用于实际的null

nullDBNull.Value不一样; DBNull.Value只是一个占位符对象。

此外,在AlternatePhoneNumber运算符执行之前,该异常来自??属性内部。 (您的代码没有演员表。)

如果customer是类型化数据集中的一行,请更改设计器中列的NullValue属性。

答案 1 :(得分:3)

null和DBNull不一样。 System.DBNull是一个实际的对象。

答案 2 :(得分:3)

问题是AlternatePhoneNumber是一个字符串。 DBNull不是。

请改为尝试:

AlternatePhoneNumber = (customer.AlternatePhoneNumber as string) ?? ""

答案 3 :(得分:2)

DBNull是一个具有单个值的类型,与空字符串引用不同,这就是您不能使用??的原因。你可以这样做:

string alternativePhoneNumber = DBNull.Value.Equals(customer) ? string.Empty : ((Customer)customer).AlternatePhoneNumber;

答案 4 :(得分:2)

这样做:

public T IfNull<T>(object o, T value)
{
   return (o == DbNull.Value) ? value : (T)o;       
}

答案 5 :(得分:1)

正如其他回复所述,null表示引用无对象的引用,而DBNull是ADO.NET提供的类,当字段或值为时指示在数据库(或在DataTable中)为NULL。

虽然您可以使用conditional (ternary) operator (?:)执行您想要的操作:

AlternatePhoneNumber = customer.AlternatePhoneNumber is DBNull 
                           ? "" 
                           : customer.AlternatePhoneNumber;

我倾向于将其包裹在extension method

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( "" );

答案 6 :(得分:1)

DBNull不是真正的“空”。

“??” - 运算符仅检测null - 引用,而不是模拟“null”行为的对象。