10

In a mixed code project (VB and C#) we were debugging some old Visual Basic code like this:

If Request.Params("xxx") <> "" Then
   'do something

I considered this a bug as Request.Params could be null, in which case the statement would've become false which wasn't the idea.

So I thought. I just found out -- again -- that VB's Nothing and C#'s null are not the same things and Nothing is not the same as null. In fact:

if(String.Empty == null)          // in C# this is always false (correct)
If String.Empty = Nothing Then    ' in VB this is always true (????)

How is this even possible? Is this some backward compatibility issue?

0

3 Answers 3

16

Nothing has a special meaning in VB for strings. To test whether a string reference is null, you need:

If value Is Nothing

From the VB comparison operators documentation:

Numeric comparisons treat Nothing as 0. String comparisons treat Nothing as "" (an empty string).

I suspect this is just for backward compatibility with VB6 - it's not something I'd be happy with, if I were a VB developer.

A comparison of the form

If value = Nothing

is compiled to a call to Microsoft.VisualBasic.CompilerServices.Operators.CompareString which returns 0 (i.e. equal) if one operand is null and the other is empty.

Sign up to request clarification or add additional context in comments.

7 Comments

Yes, thanks, that I understand :). But the first part of your answer is intriguing. Equals should give a reference equals when compared to Nothing, should it not?
Ah, ignore my previous comment. You edited meanwhile. That's more like it, thanks for the reference. I'm not so happy with it either. Any (more) ideas on the "why" part? Sounds a lot like Perl: everything's a string until further notice.
@Abel: It's far too late to change the behaviour now. They could have done it at the VB6 / VB7 point, but decided not to. They tried to preserve compatibility in many places, where they could. They don't particularly want people to use VB6 now, as far as I'm aware.
@Abel - For .NET 4.0, they've brought things closer in terms of access to functionality, not making the two languages identical but spelt differently - if they did that, why have two languages? But Nothing is a strange and magical beast in VB.Net - In generic code, it's sometimes closer to being default(T)
@Damian: that's a good comparison, thanks! @Jon: thanks for the update, I second your opinion :)
|
4

In vb6, the default value for a string variable was an empty string. A vb6 programmer relying upon such behavior would be no "worse" than a C programmer relying upon default-zero initialization of int variables; both behaviors were specified as part of the language.

Further, in COM (the framework upon which previous versions of VB6 were based), any time a reference to string was created, someone would have to manually dispose of it. Since the most commonly used string was the empty string, many COM methods are explicitly documented as regarding a null pointer as equivalent to an empty string. This means that a function returning an empty string or passing one as a value parameter or returning one may simply pass a null pointer without having to allocate anything; the recipient of the null pointer will then not have to de-allocate anything.

Because Objects in .net do not require explicit deallocation, the performance advantages of regarding a null reference as an empty string no longer apply. Nonetheless, methods which are called from code that might expect behavior similar to that of COM methods will often regard null string references as being the same as empty strings.

1 Comment

Interesting considerations and thoughts, esp. the comparison with COM. Thanks for adding it to this rather old question +1 ;)
1

You want

If Not String.IsNullOrEmpty(Request.Params("xxx") Then
    ...
End If

Or

if (!String.IsNullOrEmpty(Request.Params("xxx")) {
    ...
}

4 Comments

Yes, likely. But that's not the question here... The question is why perceived (in)equality is not actual (in)equality in VB. Why Nothing is not null, while often it is.
Yeah just misread, still this helps avoid this problem. = in VB.NET is different from == as Jon Skeet clarifies (should be the accepted).
I think the main point is that in BASIC, string is not a pointer, it is just zero or more characters. Therefore it is not possible to compare to NULL.
Even in BASIC, string is a pointer, but it is hidden by the language. This is VB.NET, not BASIC. Pointers have become close to extinct in .NET (safe for some unsafe code) and have been replaced by references. Any language for .NET is bound to the CLR specification, which means a string is a reference type that is treated specially (i.e.: read-only).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.