c#中的null,DBNull,Empty
1.DBNull
DBNull在DotNet是单独的一个类型,该类只能存在唯一的实例,DBNULL.Value,DBNull唯一作用是可以表示数据库中的字符串,数 字,或日期,为什么可以表示?原因是DotNet储存这些数据的类(DataRow等)都是以 object 的形式来储存数据的。对于 DataRow , 它的 row[column] 返回的值永远不为 null , 要么就是具体的为column 的类型的值 。 要么就是 DBNull 。 所以 row[column].ToString() 这个写法永远不会在ToString那里发生NullReferenceException。DBNull 实现了 IConvertible 。但是,除了 ToString 是正常的外,其他的ToXXX都会抛出不能转换的错误。
您可以通过将从数据库字段检索到的值传递给 DBNull.Value.Equals 方法,确定该字段值是否为 DBNull 值
2. Null
在面向对象的编程语言中,null表示不存在对某个对象的引用.所以说string s =null的意思是定义了一个string类的引用s,但是s不指向任何地方.而string s = " "表示空字符串。在内存中有明确的指向。
3. String s = "" 和string s = string.empty
如果判断为空,则if(string.length==0)>string.empty>string=="".
调用string的length==0作比较,不论字符串是否为空,此方法的效率最高.
string的isNullOrEmpty()方法的效率基本不变,无论字符串是否有值;
== string.Empty和== ""两种方法在3个变量测试的实验中效率相对较低,但是两者再和对方比较的时候会出现效率降低的情况,见上图;
原因是什么呢?我们来看看对应的il代码:
1
.locals init ([0] class [System]System.Diagnostics.Stopwatch sw,2
[1] string sEmpty1,3
[2] string sEmpty2,4
[3] string sEmpty3,5
[4] int32 i,6
[5] bool CS$4$0000)7
IL_0000: nop8
IL_0001: newobj instance void [System]System.Diagnostics.Stopwatch::.ctor()9
IL_0006: stloc.010
IL_0007: ldsfld string [mscorlib]System.String::Empty//将指定字段的值推送到堆栈上。 ldsfld 指令将静态(在类的所有实例中共享)字段的值推送到堆栈上。返回类型是与传递的元数据标记 field 关联的类型。11

12
IL_000c: stloc.113
IL_000d: ldstr ""//将对字符串的对象引用推送到堆栈上,ldstr 指令推送对表示在元数据中存储的特定字符串的新字符串对象的对象引用(O 类型)。14
IL_0012: stloc.215
IL_0013: ldstr "StringNotEmpty"//将对字符串的对象引用推送到堆栈上,ldstr 指令推送对表示在元数据中存储的特定字符串的新字符串对象的对象引用(O 类型)。16
IL_0018: stloc.317
IL_0019: ldloc.018

两者的差别由于推送到堆栈上的内容不同,前者是静态共享值推送到堆栈,后者是字符串对象的地址推送到堆栈.
浙公网安备 33010602011771号