Vil*_*lx- 69 .net history dbnull rationale
在.NET中有一个null引用,它在任何地方用来表示对象引用是空的,然后有DBNull数据库驱动程序(和其他几个)用来表示......几乎相同的东西.当然,这会产生很多混乱,转换例程必须被制作出来,等等.
那么为什么最初的.NET作者决定这样呢?对我来说没有任何意义.他们的文档也没有意义:
DBNull类表示不存在的值.例如,在数据库中,表行中的列可能不包含任何数据.也就是说,该列被认为根本不存在而不仅仅是没有值.DBNull对象表示不存在的列.此外,COM interop使用DBNull类来区分VT_NULL变量(表示不存在的值)和VT_EMPTY变量(表示未指定的值).
什么是关于"不存在的列"的废话?存在一列,它只是没有特定行的值.如果它不存在,我会尝试访问特定的单元格,而不是DBNull!我可以理解区分VT_NULL和之间的必要性VT_EMPTY,但是为什么不做一个COMEmpty类呢?这将是整个.NET框架中更适合的.
我错过了什么吗?任何人都可以解释为什么DBNull被发明以及它有助于解决的问题?
Mar*_*ell 166
我不同意这里的趋势.我会记录在案:
我不同意
DBNull任何有用的目的; 它增加了不必要的混淆,同时几乎没有任何价值.
经常提出的论点是null无效引用,这DBNull是一个空对象模式; 两者都不是真的.例如:
int? x = null;
Run Code Online (Sandbox Code Playgroud)
这不是"无效的参考"; 这是一个null价值.确实null意味着你想要它意味着什么,坦率地说,使用可能的值完全没有问题null(事实上,即使在SQL中我们需要正确使用null- 这里没有任何变化).同样,"空对象模式"只有在OOP术语中实际将其视为对象时才有意义,但如果我们有一个可以是"我们的值,或者"的值DBNull那么它必须是object,所以我们不能做任何有用的事情.
有很多不好的事情DBNull:
object,因为只能object持有DBNull 或其他价值DBNull"与"可能是一个值或null" 之间没有真正的区别null在1.1中使用得很好DBDataReader.IsDBNull或DataRow.IsNull- 实际上两者都不需要DBNull存在于API方面DBNull在零合并方面失败; value ?? defaultValue如果值是,则不起作用DBNullDBNull.Value 不能在可选参数中使用,因为它不是常量DBNull与语义相同null; 特别是,DBNull实际上是等于DBNull- 所以它不代表 SQL语义objectDBNull,你可能也只是测试过nullnull值就不会被发送......好吧,这里有一个想法:如果你不想发送参数 - 不要将其添加到参数集合中DBNull谈话与ADO.NET代码时,除了作为一个额外的滋扰唯一的甚至是远程我有说服力的论据曾经看到来证明存在这样的价值是DataTable在价值传递给创建一个新行时,; a null表示"使用默认值",a DBNull显式为null - 坦率地说,这个API本可以针对这种情况进行特定处理 - DataRow.DefaultValue例如,虚构比引入DBNull.Value无条件感染大量代码要好得多.
同样,这种ExecuteScalar情况充其量也是微不足道的; 如果您正在执行标量方法,则期望得到结果.在没有行的情况下,返回null似乎并不太可怕.如果你绝对需要消除"无行"和"返回一个单独"之间的歧义,那就是阅读器API.
这艘船很久以前就已经航行了,修理它的时间已经太晚了.但!请不要不认为所有人都认为这是一个"明显"的事情.很多开发商都没有看到BCL这种奇怪皱纹的价值.
我真的想知道所有这些是否源于两件事:
Nothing在VB中使用单词而不是涉及"null"的东西if(value is DBNull)"看起来像SQL" 的语法,而不是那么狡猾if(value==null)摘要:
有3个选项(null,DBNull或实际值)仅在有真实示例需要消除3种不同情况之间的歧义时才有用.我还没有看到我需要代表两个不同的"空"状态的场合,因此已经存在并且具有更好的语言和运行时支持,这DBNull完全是多余的null.
Col*_*kay 45
关键是在某些情况下,数据库值为null和.NET Null之间存在差异.
例如.如果您使用ExecuteScalar(返回结果集中第一行的第一列)并且您返回null,则表示执行的SQL未返回任何值.如果你得到DBNull,它意味着SQL返回一个值,它是NULL.你需要能够区分它们.
Rik*_*ous 13
DbNull代表一个没有内容的盒子; null表示盒子不存在.