为什么在VB.NET和C#中检查null与值之间存在差异?
为什么在VB.NET和C#中检查null与值之间存在差异?
在 VB.NET 中发生以下情况:
VB.NET 中会发生以下情况:
Dim x As System.Nullable(Of Decimal) = Nothing Dim y As System.Nullable(Of Decimal) = Nothing y = 5 If x <> y Then Console.WriteLine("true") Else Console.WriteLine("false") '' <-- I got this. Why? End If
但在 C# 中会发生以下情况:
decimal? x = default(decimal?); decimal? y = default(decimal?); y = 5; if (x != y) { Debug.WriteLine("true"); // <-- I got this -- I'm with you, C# :) } else { Debug.WriteLine("false"); }
为什么会有差别?
因为x <> y
返回的是Nothing
而不是true
。因为x
没有定义而导致这个结果没有定义。(类似于 SQL 的 null)。
注意:VB.NET 中的Nothing
与 C# 中的 null
不同。
您还必须只在Nullable(Of Decimal)
有值时才比较其值。
因此,以上的 VB.NET 比较类似于以下内容(看起来不太正确):
If x.HasValue AndAlso y.HasValue AndAlso x <> y Then Console.WriteLine("true") Else Console.WriteLine("false") End If
VB.NET 的语言规范:
7.1.1 Nullabe 数值类型
...一个可 null 的数值类型可以包含与这个类型的不可为 #null 值的版本相同的值,以及 null 值。因此,对于可 null 的数值类型,变量赋值Nothing
会将该变量的值设置为 null 值,而不是数值类型的零值。
例如:
Dim x As Integer = Nothing Dim y As Integer? = Nothing Console.WriteLine(x) ' Prints zero ' Console.WriteLine(y) ' Prints nothing (because the value of y is the null value) '
VB.NET和C#.NET是不同的编程语言,由不同的团队构建,并对使用方法做出不同的假设;在此情况下是对NULL比较的语义。
我的个人偏好是VB.NET的语义,其本质上为NULL赋予了“我还不知道”的语义。然后比较5和“我还不知道”的自然结果是“我还不知道”;即NULL。这还具有将NULL在大多数(如果不是全部)SQL数据库中的行为镜像的额外优点。同时,这也是解释三值逻辑更标准的(比C#的)方法,如此处所解释的。
C#团队对NULL的含义做出了不同的假设,导致你显示的行为差异。Eric Lippert写了一篇关于C#中NULL含义的博客。根据Eric Lippert的说法:“我还写过有关VB/VBScript和JScript中null的语义的博客,这里和这里”。
在任何存在NULL值的环境中,重要的是要认识到排除中间法则(即A或 ~A是证明为真的命题)不再可靠。
更新:
bool
(而非bool?
)只能取TRUE和FALSE值。然而,一个实现了NULL的语言必须决定NULL如何在表达式中传播。在VB中,表达式5=null
和5<>null
都返回false。在C#中,对可比较的表达式5==null
和5!=null
,只有第二一【已更新:2014-03-02 - PG】个返回false。但是,在任何支持NULL的环境中,程序员必须了解语言所使用的真值表和NULL传播。
更新
Eric Lippert在评论中提到的有关语义的博客文章现在在以下网址上: