I present for your reading enjoyment, my newest soap-box: eliminating the use of null in databases and code as much as possible. I realize the implications this has. I realize that Microsoft, under pressure from a lot of developers who wanted to further bastardize null, introduced nullable value types in the 2.0 version of the framework. But I think I can make a rock-solid argument for why 1) nulls are not intended to drive business or programmatic logic and 2) should only be allowed in code or database on the rarest of occasion.
Null Isn't A Value
In .Net, Null isn't a value. Null wasn't put into the framework for your uses. In .Net you have two kinds of types: value types and reference types. A value type is defined by a struct or enum and places it's data directly on the stack. A reference type is defined by a class and is called a reference because any instance of this type is actually stored out in a blob of dynamically allocated and managed memory called the heap. The variable which represents this instance is placed on the stack and is actually a pointer to the spot in the heap where the actual instance resides.
Null is what happens when an instance variable doesn't point to a memory address on the heap. Null is not an actual value which is why (traditionally) value types cannot be null because they're not an address pointer but a value directly on the stack. The sole reason for the null keyword (or Nothing for you VB folks) is so that you can programmatically test for and handle the unfortunate case when your reference type variable isn't pointing to anything you can use. The reason you get a NullReferenceException in the framework isn't because Microsoft loves to annoy you, it's because you're trying work with an object instance that no longer exists.
Testing For Null vs. Testing For Constants
A common argument against the "no more nulls" campaign I'm on comes up when discussing UI binding and validation. You may not want to display underlying values in the UI to the user if the values weren't populated from something like a database. As I understand it, the code would look something like:
if (class.Property != null)
{
textBox.Text = class.Property;
}
Well, what I don't get is how that's any different from:
if (class.Property != EMPTY_CONSTANT)
{
textBox.Text = class.Property;
}
Where EMPTY_CONSTANT would be for whatever value type you were testing for whether that's EMPTY_DATETIME or EMPTY_STRING (though that's really unnecessary). As you can see, the point is pretty moot. You can just as easily test for a constant, it's still readable and you protect everyone from NullReferenceExceptions.
Avoiding Null In The Database
Harder for me to argue this one other than to say that I believe default values and NOT NULL exist in RDBMs for a great reason! If you allow nulls in database columns, you're going to end up having to write additional logic to code around them everywhere. The one great exception I'm aware of is foreign key columns. A column marked as FK has to have a value which ties to a row in the parent table. This means if you don't have a row for the FK, it has to be null. The work around for this would involve putting a non-sense row in the related table which would need to be filtered out all over the place (bad).
Tags: null, .net