C#中的NULL和vb.net中的Nothing有什么不同?
Console.WriteLine(Nothing = "") => True
对比
Console.WriteLine(null==""); => False
我的理解是,null
和 Nothing
是相同的。但上面的代码清楚地说明它们并不相同。
C# 中的 null
在 VB.NET 中等价于什么?
Nothing
和 C# 中的 null
之间的区别。Nothing
的说明:
如果您阅读 Microsoft 文档中关于 默认值表达式 的描述,您会注意到 vb.net 中的
Nothing
是一个特殊的字面量;它没有类型,并且可以转换为类型系统中的所有类型,包括类型参数。当转换为特定类型时,它等价于该类型的默认值。
Nothing
和 C# 中的 default(T)
具有类似的行为。Dim isSomething As Boolean = Nothing ' = False
Dim amount As Integer = Nothing ' = 0
Dim value As String = Nothing ' = null (notice not empty string!)
Dim value As String = Nothing
If value.Equals("") Then ' will throw NullReferenceException
End If
Nothing
和空字符串""
使用"="
运算符在vb.net中是特殊情况,因为对于字符串来说Nothing
将会被解析为null
。String
的关系运算符,来自Visual Basic语言规范的说明:String.Equals
方法或Is
运算符。这两者并不相同,Vb.net
中的 Nothing
相当于 C# 中的 default(T)
。
C# 中的 null 在 VB.NET 中有什么等价物?
在 C# 中,您无法将 null
设置为值类型,因此对于引用类型(String
),在 vb.net 中与 C# 中的 null
等效的是 Nothing
。
例如:(null == default(String))
Integer
中存储Nothing
?实际上,如果您删除= Nothing
,您的示例仍将工作并产生相同的结果,因为VB自动初始化变量,而C#则不然。 - Racil HilanString
被 MSDN 视为数据类型,尽管它实际上是一个引用类型,正如你所提到的。然而,这并不像你所说的“与普遍信仰相反”,每个好的程序员都必须知道这一点。这就是为什么我没有费心解释它,但还是感谢你的澄清 :) - Racil HilanNothing
并不总是等同于default(T)
,在某些情况下它实际上等同于null
。它是一个具有双重用途的关键字,就像=
运算符一样。这很令人困惑,语法也很差,但我们必须接受它。 - Racil Hilan在你的代码中,VB猜测你正在比较字符串,因为其中一个操作数是String
类型。在String
比较中,Nothing
等同于空的String
""
。然后它进行值比较,返回True
。
使用Is
来比较引用:
Console.WriteLine(Nothing Is "") '=> False
Nothing =“”
)不会这样做,但是例如如果一个操作数是“Single”,而另一个操作数是“Double”。我更新了您的答案,以删除前两个不正确的行。如果您不同意,请回滚。 - Racil HilanMicrosoft.VisualBasic.CompilerServices.Operators::CompareObjectEqual
。(参见https://msdn.microsoft.com/en-us/library/microsoft.visualbasic.compilerservices.operators.compareobjectequal(v=vs.110).aspx)。但是我认为它已经足够复杂,你所做的修改是很好的。 - SSSString
类型的默认值是 null
,而非空字符串 ""
。 - FabioString
实际上是一个引用。感谢您的评论,我会相应地更新答案。我希望SSS能接受这个。 - Racil HilanNothing
相当于C#中的null
,所以你的理解是正确的,至少部分正确(因为这只是Nothing
关键字的一个用法)。虽然这已经反映在MSDN文献中,但最近已经逐渐消失,并在许多注释中被null
一词所取代。您的困惑来自VB的行为和特性与C#不同,来自其他语言的程序员没有经验,会对结果感到困惑。Nothing
视为空字符串""
,根据MSDN:
现在,为什么VB会这样做呢?这是因为VB使用数字比较将Nothing视为0。字符串比较将Nothing视为""(一个空字符串)。
Nothing
关键字来表示两个不同的事物(类似于它如何使用=
运算符来表示两个不同的事物,即赋值和比较)。第一个用法相当于我上面提到的C#中的null
。第二个用法相当于C#中的default(T)
运算符。与=
运算符一样,VB根据上下文知道如何使用Nothing
。例如:Nothing
用作null
:Console.WriteLine(s Is Nothing) //C#: (s == null)
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#都会将一个操作数转换为与另一个操作数匹配的类型。例如,如果您比较double和integer值,则VB和C#都将返回true
此行:
Console.WriteLine(5.0 = 5) //C#: (5.0 == 5)
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))
Default(T)
的含义。如果你反汇编 Dim s As String = Nothing
,生成的 IL 代码会将 s
设置为 null 引用,正如你所期望的那样 (ldnull
, stloc.0
)。只有在比较时,它才会通过 Microsoft.VisualBasic.CompilerServices.Operators::CompareObjectEqual
转换为空字符串。 - SSSNothing
和空字符串 ""
进行字符串比较是一个特殊情况,与 default(T)
没有任何关系。在这种比较中,Nothing
实际上就像是 null
。因此,你的最终答案是对这个问题的很好回答。我只想添加一些有用的信息,例如在赋值期间将 Nothing
视为 default(T)
,以及自动转换会让人们误认为 Nothing
不是 null
的其他特殊情况。实际上它是 null
,而 default(T)
行为是次要的使用。 - Racil Hilan
Nothing
和null
的含义已经被非常明确地定义了。 - jrhNothing
更像default
,那么我希望在VB.Net中Nothing = ""
为false,因为string
是引用类型,除非它不是。 - juharrnull
完全等效的内容,还是只是寻找类似于null
的东西(即Nothing
)?请更新您的帖子以澄清,这样这里就只有一个问题了。 - jrh