为什么在VB.NET和C#中检查null与值之间存在差异?

14 浏览
0 Comments

为什么在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");
}

为什么会有差别?

admin 更改状态以发布 2023年5月25日
0
0 Comments

因为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) '

0
0 Comments

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=null5<>null都返回false。在C#中,对可比较的表达式5==null5!=null,只有第一【已更新:2014-03-02 - PG】个返回false。但是,在任何支持NULL的环境中,程序员必须了解语言所使用的真值表和NULL传播。

更新

Eric Lippert在评论中提到的有关语义的博客文章现在在以下网址上:

0