什么也没有 = 字符串.Empty(为什么它们相等?)

28

第一个if语句为什么会被判定为True呢?如果使用"is"而不是"=",它就不会被判定为True。如果将String.Empty替换为"Foo",它也不会被判定为True。因为String.Empty和"Foo"都属于同一类型的字符串,所以为什么一个被判定为True,另一个却不是呢?

    //this evaluates to true
    If Nothing = String.Empty Then

    End If

    //this evaluates to false
    If Nothing = "Foo" Then

    End If

1
你是否正在使用.Equals()方法进行比较? - Amber
我添加了一段代码片段。实际上,我并不需要对null和空字符串进行比较,只是好奇为什么那个语句会被判断为真。 - Justin Helgerson
Nothing=String.Empty 但是 String.Empty != Nothing。我刚刚发现了这个。 - dgo
4个回答

23

在VB.net中,没有一个类型的默认值。根据语言规范第2.4.7节所述:

Nothing是一个特殊的字面量; 它没有类型,并且可以转换为类型系统中的所有类型,包括类型参数。当转换为特定类型时,它等同于该类型的默认值。

因此,当您针对String.Empty进行测试时,Nothing会被转换为具有长度为0的字符串。应使用Is运算符来测试Nothing,而String.Empty.Equals(Nothing)也将返回false。


11
使用 VB.NET 的 = 运算符比较字符串时,它使用的是 StrCmp 而不是 op_Equality 运算符。我猜测这是为了向后兼容性考虑。 - Rebecca Chernoff
1
她的意思是:在C#中,VB.NET中的Nothing等同于default(T),而不是NULL。 - Stefan Steiger
4
但是String的默认值难道不是Nothing而不是""吗? - recursive
6
@recursive: 是的,没错。这对于VB也是适用的。主要答案是错误的,真正的原因在Rebecca的评论中给出:当你使用=比较字符串时,VB.NET会调用StrCmp。这个方法有特殊的代码来处理"" = Nothing,使其为真。如果你尝试使用"".Equals(Nothing),你会得到false。 - jods
4
这个回答完全误导了:default(String)null,而不是 String.Empty,因为 String 是一个引用类型。正确的答案是来自 Heinzi 的答案,或者你在关于 StrCmp 的评论中提到的答案。请修改你的回答,以便供将来参考。 - Teejay
显示剩余3条评论

14

这是VB的=<>运算符的一种特殊情况。

在第11.14节中,语言规范指出:

进行字符串比较时,null引用等同于字符串文字 ""。


如果您对细节感兴趣,我在这里编写了有关VB.NET中vbNullStringString.Empty""Nothing的详细比较:


2
这应该是被接受的答案。当前被接受的答案是错误的,正确的答案只在其评论中给出。 - GSerg

3

关于这个话题,如果您使用一个被初始化为 "nothing" 的字符串变量来赋值给一个 SqlParameter 属性的 "value",那么该参数将被忽略,不会包含在发送到服务器的命令中,并且会抛出缺少参数错误。 如果您使用 string.empty 来初始化该变量,则一切都会顺利进行。

//This doesn't work
Dim myString as String = nothing
mySqlCommand.Parameters.Add("@MyParameter", SqlDbType.Char).Value = myString

//This works    
Dim myString as String = string.empty
mySqlCommand.Parameters.Add("@MyParameter", SqlDbType.Char).Value = myString

3
将值设为DBNull.value而不是nothing。 - Bernhard Döbler
它指出了一个问题,如果外部库不是用VB编写的,那么库的作者可能不知道VB中nothing和empty string之间的歧义。因此,在VB代码中使用时,用户必须小心传递nothing或empty string。 - Gqqnbig
在VB中,“Nothing”和“String.Empty”之间没有歧义。它们比较真实,但它们并不相同。将“Nothing”作为参数值传递会导致该参数根本不被发送,C#中的“null”也是如此。传递“DBNull.Value”会导致数据库空值作为参数值被发送,C#中也是如此。传递“”会导致一个空字符串被发送到数据库,C#中也是如此。 - GSerg

2

试试这个:

Console.WriteLine("Is String.Empty equal to Nothing?: {0}", String.Empty.Equals(Nothing))

= 操作符不强制相等类型,而字符串对象的 .Equals() 方法和 Is 操作符会强制相等类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接