C# null,string.Empty,"",DBNull 的区别
【null】
null 在c# 中是一个关键字,表示不引用任何对象的空引用的文字值。 null
是引用类型变量的默认值。 普通值类型不能为 null。
null 在 vs 中定位不出来具体是怎么定义的。一般通过类名映射过来的关键字,都可以定位到声明位置。所以null是比较特殊的。
这个东西要跟踪源头还比较麻烦,感觉找不到具体定义。
msdn上说明很简单:null
关键字是表示不引用任何对象的空引用的文字值。 null
是引用类型变量的默认值。 普通值类型不能为 null。
stock overflow 上有一段回答:
there are three things in c# that "null" can be. a reference, a pointer, and a nullable type.
the implementation of c# on the clr represents a null reference by zero bits. (where the number of bits is the appropriate size to be a managed pointer on the particular version of the clr that you're running.)
unsurprisingly, a null pointer is represented the same way. you can demonstrate this in c# by making an unsafe block, making a null pointer to void, and then converting that to intptr, and then converting the intptr to int (or long, on 64 bit systems). sure enough, you'll get zero.
以下翻译(来自google在线翻译):
c#中有三个“null”可以。 引用,指针和可空类型。
clr上的c#实现表示零位的空引用。 (其中位数是适合您正在运行的clr的特定版本上的托管指针的大小。)
不出所料,空指针以相同的方式表示。 您可以在c#中通过创建一个不安全的块,将空指针转换为void,然后将其转换为intptr,然后将intptr转换为int(或64位系统上的long)来证明这一点。 果然,你会得到零。
stack overflow 上的这个回答是基本从比较底层说明的。
那么咱们也从相对比较底层看下c/c++中null的定义。
来自 https://zh.cppreference.com/w/c/types/null
c:
c++
【string.empty】
这个是 string 类中的一个制度静态变量。也就肯定的说明了 string.empty 是一个存在静态对象。这个就跟 null 区别开了。那到底具体是个什么呢?
string.empty 其实就是 “”。
msdn解释:
string.empty 虽然跟 “” 是相等的,但是一般在给 string 初始化为空字符串的时候,一般建议用string.empty,因为“”在赋值给string对象的时候,是你新创建了一个空字符串,而用empty是将你的字符串对象指向了全局的只读的空字符串,这样相对来说性能能优化一些。
【“”】
“” 代表一个空字符串。什么意思,首先是一个字符串对象,但是特殊的是,这个字符串没有内容,这可绝非 null。
个人经验简单形容下 null 和 “”。引用类型好比书目录,类对象好比书中内容。如果引用类型不为null,那么目录后面就有页码,如果为null,那么目录后面的页码就为0或者没有页码。那么没有页码,你说这个目录怎么找页数,也就是空引用了。
【dbnull】
咱先看msdn注解:
dbnull类表示不存在的值。 例如,在数据库中,表的行中的列不可能包含任何数据。 也就是说,列被视为根本不存在,而不是只是不具有值。 一个dbnull对象都表示不存在的列。 此外,com 互操作使用dbnull类,以区分 vt_null 变体,用于指示不存在的值和 vt_empty 变体,用于指示未指定的值。
dbnull类型是一个单一实例类,这意味着只有一个dbnull对象存在。 dbnull.value成员表示单独dbnull对象。 dbnull.value 可用于显式将不存在的值分配到数据库字段中,尽管大多数的 ado.net 数据提供程序自动分配的值dbnull字段没有有效的值。 您可以确定从数据库字段中检索某个值是否dbnull通过将为该字段的值传递值dbnull.value.equals
方法。 但是,某些语言和数据库对象提供一些方法,使其更轻松地确定数据库字段的值是否为dbnull.value。 其中包括 visual basicisdbnull
函数,convert.isdbnull方法,datatablereader.isdbnull方法,和idatarecord.isdbnull方法。
不要混淆这一概念null
在面向对象的编程语言与dbnull对象。 在面向对象的编程语言中,null
表示不存在的对象的引用。 dbnull 表示一个未初始化的变量或不存在的数据库列。
从上面注解可以看出,dbnull只要用在数据库和com互操作中。而dbnull中有个value字段,这个字段是一个静态只读字段,也就是全局唯一静态dbnull对象,不是null。
当我们在用ado.net操作数据库时,遇到数据库返回字段值为null时,就需要用dbnull来判断,而不能用null来判断。
看看msdn对dbnull.value的注解:
dbnull 是一个单一实例类,这意味着可以存在此类的此实例。
如果数据库字段有缺失数据,则可以使用dbnull.value属性来显式分配dbnull对象的字段的值。 但是,大多数数据访问接口自动执行此操作。
若要评估的数据库字段,以确定它们的值是否dbnull,可以将传递到的字段值dbnull.value.equals
方法。 但是,很少使用此方法,因为有多种其他方法来评估缺少数据的数据库字段。 其中包括 visual basicisdbnull
函数,convert.isdbnull方法,datatablereader.isdbnull方法,idatarecord.isdbnull方法和其他几种方法。
所以这下就明白了吧,这就是为什么我们用idatareader读取数据库字段信息时,要用dbnull.value来判断是否为空,然后在转换或者其他操作。
上一篇: ios-Swift的只读属性和懒加载对比
下一篇: C语言 顺序表的实现 (动态)