我有一个Oracle数据表,提取的列为null。所以我想保持代码很好,很简单,我会使用??操作数。 AlternatePhoneNumber是我的C#模型中的一个字符串。
AlternatePhoneNumber = customer.AlternatePhoneNumber ?? ""
然而,即使使用该代码,我仍然会收到错误。
System.InvalidCastException: Unable to cast object of type 'System.DBNull' to type 'System.String'.
我知道错误意味着什么,但为什么?在DBNull上不可用?不是null并且DBNull基本相同吗?
谢谢。
答案 0 :(得分:15)
??
运算符仅适用于实际的null
。
null
和DBNull.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”行为的对象。