What is the difference between Nothing and Null (or actually DBNull.value)?
IntroductionIf you are confused about the difference between Nothing and Null (or more precisely DBNull.Value) in VB.NET, you’re not alone. Just Google Nothing vs. NULL and you’ll see what I mean.
The keyword Nothing is used to specify that a reference type is not pointing to anything.
DBNull.Value is a singleton object used to indicate that a database type has a database value of Null.
Not enough? OK. Read on . . .
I believe a potential cause for the misunderstanding between the two values may arise from
- having so many options in previous versions of VB for describing special states of variables—for example, Nothing, Empty, NULL, IsMissing, “” (empty string), etc.,
- a similarity in meaning between the words Null and Nil in data structure literature
- loose typing in previous versions of VB.
I'll point out where I think this occurs within this discussion. We'll first look at Nothing, then Null and then explore a sample application to illustrate things further. Let's start our discussion with Nothing (I couldn't resist).
NothingTo understand the difference between Nothing and Null, I think it helps to understand what a reference type variable is. From the .NET Framework Developer's Guide: Common Type System Overview:
Reference types store a reference to the value's memory address, and are allocated on the heap. Reference types can be self-describing types, pointer types, or interface types. Reference types are sometimes referred to as pointers in other programming languages such as C, C++. and Pascal.
You can think of reference types just like the pointers you encountered in your data algorithms class when working with binary trees and linked lists. They are the same thing.
However, value types (the other type of variables in .NET), can’t be compared to Nothing or Null. Value types are types such as Integers and Bytes. From the Visual Basic Language Reference: IsNothing Function:
IsNothing is intended to work on reference types. A value type cannot hold a value of Nothing and reverts to its default value if you assign Nothing to it. If you supply a value type in Expression, IsNothing always returns False.
You may recall the term Nil from the same data algorithms class. Nil means that the pointer is not pointing to anything, and this happens to be the definition of Nothing. From the Visual Basic Language Reference: Nothing (Visual Basic):
When you assign Nothing to an object variable, it no longer refers to any object instance.
Sounds like Nil to me. But, some people might think Nil and Null are the same thing. I think this may be because the word Null is also sometimes used to mean Nil in data algorithm discussions. In that context, it's fine. However, in the VB.NET database programming world, Null means something totally different.
NullIn the VB.NET world, Null is a database term—more specifically, DBNull.Value. In .NET, the term DBNull really presses the point, doesn't it? You know we're talking about a database "thing" because of the leading DB.
DBNull.Value is what used to be Null in VB 6.0. But, the way Null was internally represented in VB 6.0, you could use it in other places and get away with it. You can't anymore.
I like the deliberate naming of DBNull because it stresses the point that we are talking about a value in the context of databases. For more context, ANSI-SQL—the guys who define the syntax of SQL—defines NULL as
a special value, or mark, that is used to indicate the absence of any data value. (ANSI-92)
NULL in SQL is not a "data value", but rather an indicator that we have missing data.
From the .NET Framework Class Library: DBNull Class,
DBNull is a singleton class, which means only one instance of this class can exist. That sole instance is DBNull.Value.
When you set a variable to DBNull.Value, you are just pointing to the one and only DBNull.Value instance.
Source CodeStart VisualStudio 2005 (or some version thereafter if this article survives that long), create a new console application, cut and paste this code in and run it.
Module NothingAndNulls Sub Main() Dim P As Object Dim I As Integer Debug.Print("1. P is not set to anything.") Debug.Print("P Is Nothing: " & (P Is Nothing)) Debug.Print("P Is DBNull.Value: " & (P Is DBNull.Value)) Debug.Print("----------") P = New Object() Debug.Print("2. P is set to a new object.") Debug.Print("P Is Nothing: " & (P Is Nothing)) Debug.Print("P Is DBNull.Value: " & (P Is DBNull.Value)) Debug.Print("----------") P = DBNull.Value Debug.Print("3. P is pointing to the special singleton class DBNull.") Debug.Print("P Is Nothing: " & (P Is Nothing)) Debug.Print("P Is DBNull.Value: " & (P Is DBNull.Value)) Debug.Print("----------") I = Nothing Debug.Print("4. I is not set to anything.") Debug.Print("I Is Nothing: " & (IsNothing(I))) Debug.Print("I Is DBNull.Value: " & (IsDBNull(I))) End Sub End Module
After you run it, you'll get the following output. Study this output. It is consistent with the discussion above.
1. P is not set to anything. P Is Nothing: True P Is DBNull.Value: False ---------- 2. P is set to a new object. P Is Nothing: False P Is DBNull.Value: False ---------- 3. P is pointing to the special singleton class DBNull. P Is Nothing: False P Is DBNull.Value: True ---------- 4. I is not set to anything. I Is Nothing: False I Is DBNull.Value: False
Step 1 occurs when we have done nothing with P and inspect it right after it is declared. As expected, P is Nothing. Since we have not assigned it to point to the DBNull.Value object, IsDBNull() is false.
In Step 2, we create a new, generic object and point P to it. Now, P is not Nothing; it is pointing to something, specifically, the new object we just created. This means that it can't be pointing to the DBNull.Value object. So, as expected, IsDBNull() returns false.
Now, in Step 3, we set P to DBNull.Value (finally). Now here's where you need to watch closely. IsNothing returns false. This makes sense if you think about it. P is a pointer. DBNull.Value is an object. P is pointing to that object; therefore, it is not Nothing. And finally, in this case, IsDBNull() returns true because in this case, P is actually pointing to DBNull.Value.
And, in Step 4, just for kicks, we play around with an Integer; a value type. We set it to Nothing; which is allowed as discussed above. However, when we immediately check to see if it is equal to Nothing, we find that it is not! That's because as soon as we set it to Nothing, it gets set right back to a new default value (zero in this case).
There you are . . . Nothing and Null in VB.NET.
