28

Why does the first if statement evaluate to true? I know if I use "is" instead of "=" then it won't evaluate to true. If I replace String.Empty with "Foo" it doesn't evaluate to true. Both String.Empty and "Foo" have the same type of String, so why does one evaluate to true and the other doesn't?

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

    End If

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

    End If
Justin Helgerson
  • 24,900
  • 17
  • 97
  • 124

4 Answers4

23

Nothing in VB.net is the default value for a type. The language spec says in section 2.4.7:

Nothing is a special literal; it does not have a type and is convertible to all types in the type system, including type parameters. When converted to a particular type, it is the equivalent of the default value of that type.

So, when you test against String.Empty, Nothing is converted to a string, which has a length 0. The Is operator should be used for testing against Nothing, and String.Empty.Equals(Nothing) will also return false.

Rebecca Chernoff
  • 22,065
  • 5
  • 42
  • 46
  • Do you know the reason behind automatically converting Nothing to a string on the fly when I do the comparison? What is the benefit of this? – Justin Helgerson Apr 13 '10 at 21:24
  • 11
    When using the = operator with a string, VB.NET uses StrCmp, rather than op_Equality. I'd speculate this was for backwards compatibility reasons. – Rebecca Chernoff Apr 13 '10 at 21:51
  • 1
    What she means to say: VB.NET Nothing = default(T) in C#, not NULL – Stefan Steiger Jan 18 '13 at 05:54
  • 4
    But isn't the default value for `String` `Nothing` instead of `""`? – recursive Mar 26 '13 at 23:14
  • 6
    @recursive: Yes, it is. And that holds for VB as well. The main answer is incorrect and the real reason is given in the comment by Rebecca: VB.NET calls StrCmp when you compare strings with =. This method has special code to handle "" = Nothing as true. If you'd try "".Equals(Nothing) you'd get false. – jods Feb 28 '14 at 17:29
  • @Quandary: Nothing *is* the equivalent of Null, and if compared with the **Is** operator would not match String.Empty. It is only the = comparison (which does not compare references) that return true. – Reinstate Monica Feb 18 '15 at 13:42
  • 1
    @afuna: Except that default(string) = null, and not "". And no, nothing is the equivalent of default(T), which is not the same as NULL, that is, only if you have a non-nullable type, like GUID... – Stefan Steiger Feb 19 '15 at 21:44
  • 4
    @RebeccaChernoff This answer is completely misleading: `default(String)` is `null`, not `String.Empty`, since `String` is a ref-type. The correct answer is the one from Heinzi, or in your comment about `StrCmp`. Please modify your answer, for future reference. – Teejay Mar 16 '17 at 16:27
14

It's a special case of VB's = and <> operators.

The Language Specification states in Section 11.14:

When doing a string comparison, a null reference is equivalent to the string literal "".


If you are interested in further details, I have written an in-depth comparison of vbNullString, String.Empty, "" and Nothing in VB.NET here:

Heinzi
  • 167,459
  • 57
  • 363
  • 519
  • 2
    This should be the accepted answer. The [currently accepted answer](https://stackoverflow.com/a/2633274/11683) is wrong and the correct answer is only given in its comments. – GSerg Apr 12 '19 at 09:29
3

Related to this topic, if you use a string variable initialized with "nothing" to be assigned to the property "value" of a SqlParameter that parameter is ignored, not included in the command sent to the server, and a missing parameter error is thrown. If you initialize that variable with string.empty everything goes fine.

//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
DanielRuzo
  • 31
  • 1
  • 3
    set value to DBNull.value instead of nothing – Bernhard Döbler Jan 29 '14 at 21:49
  • It points out a problem that if an external library is not written in VB, the author of the library might not be aware of the ambiguity between nothing and empty string in VB. So when it's used in VB code, users have to be carefull passing nothing or empty string. – Gqqnbig Sep 15 '16 at 17:29
  • There is no ambiguity between `Nothing` and `String.Empty` in VB. They compare truthy, but they are not the same. Passing `Nothing` as the parameter value results in the parameter not being sent at all, same does `null` in C#. Passing `DBNull.Value` results in the *database `null`* being sent as the parameter value, same happens in C#. Passing `""` results in an empty string being sent to the database, same in C#. – GSerg Apr 12 '19 at 09:39
2

Try this:

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

The = operator doesn't enforce equal types, whereas the .Equals() method of a string object does, as does the Is operator.

Amber
  • 507,862
  • 82
  • 626
  • 550