The final version of the accepted answer correctly answers the question. However, Fabio added some useful information to his answer, but it has a number of incorrect information and concepts. So this answer is an attempt to merge the two answers in a more complete one with the correct information.
First of all, Nothing
in VB is equivalent to null
in C#, so your understanding of that is correct, at least partially (because that's only one use of the Nothing
keyword). It's been reflected throughout the MSDN literature, although it's been fading recently and being replaced with the word null
in many comments. Your confusion arises from the behavior and features of VB which differ from C# and programmers who are coming from other languages and not experienced in VB get confused by the results.
As stated in the accepted answer, the question is considered a string comparison by VB because one of the operands is a string. In string comparisons, VB treats Nothing
the same as the empty string ""
as per MSDN:
Numeric comparisons treat Nothing as 0. String comparisons treat Nothing as "" (an empty string).
Now, why is that happening in VB? It happens because VB uses the Nothing
keyword for two different things (similar to how it uses the =
operator for two different things, assignment and comparison). The first usage is equivalent to null
in C# as I mentioned above. The second usage is equivalent to the default(T)
operator in C#. Like with the =
operator, VB knows which way to use Nothing
depending on the context. Examples:
In this line, VB uses Nothing
as null
:
Console.WriteLine(s Is Nothing) //C#: (s == null)
In these lines, VB uses Nothing
as default(T)
to assign the default value to the variable:
Dim s As String = Nothing //C#: string s = default(string);
Dim i As Integer = Nothing //C#: int i = default(int);
Finally, when comparing variables of different types, both VB and C# convert one operand to match the type of the other operand. For example, if you compare double and integer values. Both VB and C# will return true
for this line:
Console.WriteLine(5.0 = 5) //C#: (5.0 == 5)
However, VB and C# differ in what types can be converted to what. Also, the empty string ""
and null
are treated the same in string comparisons in VB, but not in C#. This makes things easier in most cases, which is something known about VB in general. So you can easily test if your string has no value like this:
Console.WriteLine(s = Nothing)
Console.WriteLine(s = "")
Both lines will return the same result because VB treats Nothing
as ""
for comparison. In C#, you cannot do that and you have to test for both like this:
Console.WriteLine(s == null && s == "")
Obviously, VB is easier and shorter than C# in this case which is the most common one. However, this comes at the cost of losing some control. In the less common cases when you only want to test for null reference, C# become obviously better because you can still use the ==
operator:
Console.WriteLine(s == null)
While in VB, you cannot use the =
operator and you have to use another one, the Is
operator:
Console.WriteLine(s Is Nothing)
Also although VB is easier in the previous point, C# is clearer. That's why from code clarity perspective, this line can be used instead in both languages with the same result:
Console.WriteLine(string.IsNullOrEmpty(s))