接受答案的最终版本正确回答了问题。然而,法比奥在他的回答中添加了一些有用的信息,但它有一些不正确的信息和概念。所以这个答案是试图将两个答案合并成一个更完整的答案。
首先,VB 中的Nothing 等同于C# 中的null,因此您对此的理解是正确的,至少部分正确(因为这只是Nothing 关键字的一种用法)。它在整个 MSDN 文献中都有体现,尽管它最近已经淡出并在许多 cmets 中被替换为 null 一词。您的困惑源于 VB 与 C# 不同的行为和特性,以及来自其他语言且没有 VB 经验的程序员对结果感到困惑。
如已接受的答案所述,VB 认为该问题是字符串比较,因为其中一个操作数是字符串。在字符串比较中,VB 将Nothing 视为与MSDN 一样的空字符串"":
数值比较将Nothing视为0。字符串比较将Nothing视为“”(空字符串)。
现在,为什么在 VB 中会发生这种情况?这是因为 VB 将 Nothing 关键字用于两个不同的事情(类似于它如何将= 运算符用于两个不同的事情,赋值和比较)。第一种用法相当于我上面提到的 C# 中的null。第二种用法相当于 C# 中的default(T) 运算符。与= 运算符一样,VB 根据上下文知道使用Nothing 的方式。例子:
在这一行中,VB 使用Nothing 作为null:
Console.WriteLine(s Is Nothing) //C#: (s == null)
在这些行中,VB 使用Nothing 作为default(T) 为变量分配默认值:
Dim s As String = Nothing //C#: string s = default(string);
Dim i As Integer = Nothing //C#: int i = default(int);
最后,在比较不同类型的变量时,VB 和 C# 都会转换一个操作数以匹配另一个操作数的类型。例如,如果您比较双精度值和整数值。对于这一行,VB 和 C# 都会返回 true:
Console.WriteLine(5.0 = 5) //C#: (5.0 == 5)
但是,VB 和 C# 的不同之处在于可以将什么类型转换为什么类型。此外,空字符串 "" 和 null 在 VB 中的字符串比较中被视为相同,但在 C# 中则不同。在大多数情况下,这使事情变得更容易,这在 VB 中是众所周知的。所以你可以很容易地测试你的字符串是否没有这样的值:
Console.WriteLine(s = Nothing)
Console.WriteLine(s = "")
这两行将返回相同的结果,因为 VB 将Nothing 视为"" 进行比较。在 C# 中,你不能这样做,你必须像这样测试两者:
Console.WriteLine(s == null && s == "")
显然,在这种情况下,VB 比最常见的 C# 更简单、更短。然而,这是以失去一些控制为代价的。在您只想测试空引用的不太常见的情况下,C# 显然变得更好,因为您仍然可以使用 == 运算符:
Console.WriteLine(s == null)
在 VB 中,您不能使用 = 运算符,而必须使用另一个 Is 运算符:
Console.WriteLine(s Is Nothing)
此外,虽然 VB 在前一点更容易,但 C# 更清晰。这就是为什么从代码清晰的角度来看,这行代码可以在两种语言中使用,但结果相同:
Console.WriteLine(string.IsNullOrEmpty(s))