C# 解释如何处理DBNull?

C# 解释如何处理DBNull?,c#,sql,datetime,dbnull,C#,Sql,Datetime,Dbnull,我有一个可空的DateTime字段“BirthDate”,现有代码就是这样处理的 info.BirthDate = (DateTime?)reader["Birthdate"]; 这会导致“无效强制转换”错误并中断。好的,我理解这是因为null的返回方式不同于sql,并且是“DBNull”类型 解决这个问题的方法是 if (reader["Birthdate"] != DBNull.Value) { info.Birthdate = (DateTime)reader["Birthdat

我有一个可空的DateTime字段“BirthDate”,现有代码就是这样处理的

info.BirthDate = (DateTime?)reader["Birthdate"];
这会导致“无效强制转换”错误并中断。好的,我理解这是因为null的返回方式不同于sql,并且是“DBNull”类型

解决这个问题的方法是

if (reader["Birthdate"] != DBNull.Value)
{
    info.Birthdate = (DateTime)reader["Birthdate"];
}

有人能解释一下为什么会这样吗?。我对DBNull的.Value部分特别迷茫。如果返回为DBNull,那么代码是如何到达该块的?

DBNull
是一个单例。只有一个例子。您可以使用
DBNull.Value
访问此实例。比较检查是否返回了
DBNull(.Value)
,如果未返回(
!=
),则知道可以安全地将其转换为
日期时间

发件人:

DBNull是一个单例类,这意味着只有该类的这个实例 类可以存在

或者,您可以使用
Convert.IsDBNull
方法:

if (!Convert.IsDBNull(reader["Birthdate"]))
{
    info.Birthdate = (DateTime)reader["Birthdate"];
}
DBNull
是一种类型,而不是值。正如@aKzenT所解释的,它是作为单例实现的,这意味着该类型只能有一个实例。获取该值的方法是通过static
.value
属性

由于任何
DBNull
实例的值和对另一个
DBNull
实例的引用都是相等的,因此比较起来很容易

另一种可能更有意义的检查方法是:

int columnIndex = reader.GetOrdinal("Birthdate");
if (!reader.IsDbNull(columnIndex)) // IsDbNull should have a string overload, but it does not.
{
    info.Birthdate = (DateTime)reader["Birthdate"];
}

哦好的,因为属性是可空的,所以它保持为零,并且跳过此块。我现在明白了。非常感谢。第三个选项是
reader[“Birthdate”]作为DateTime?
。(对第三种选择有充分的反对意见,也有充分的理由支持它。我宁愿避免这种讨论。:)啊,好的,可以。说我能在4分钟内完成。这是我第一次发帖子给SOThank,希望你能进一步澄清!。。很高兴我决定在这里发帖,而不是无缘无故地猜测。