.Net declares two types of types: Value types and Reference types.
What the difference ?
Reference types can be null while Value types cannot. So you have System.Nullable<T> for Value types you want to put null in.
int i = null; // Error
object o = null; // OK
System.Nullable<int> ni = null; // OK, System.Nullable is reference type.
It was a theory. Now go to practical samples:
While reference types can be null you have to check all arguments for null. Hmm..
It looks like old C++ days !
Compare:
C++
void f(A* a, B* b)
{
if(a == NULL || b == NULL)
return;
// The rest code
}
C#
void f(A a, B b)
{
if(a == null || b == null)
return;
// The rest code
}
So what the hack ?
Mainly it does not cause a problem for private methods but for all public you must check for null. Especially it comes in operator overloading and overloading Object.Equals functions.
And the solution comes true..
It simply you must not provide nullability for Reference types if you do not specify that.
Example:
class A
{
public static A operator+(A left, A right)
{
// In C# you must check arguments
// if(a == null || b == null)
// return;
// Because one can write:
//
// A a = null;
// A b = null;
// A c = a + b;
// In C## language you just cannot pass null here !
return …;
}
}
// In C## language you specify when null is OK
class A
{
public static A? operator-(A? left, A? right)
{
// Here we may check for null
if(left == null)
return new A(1);
if(right == null)
return new A(2);
return new A(3);
}
}
That's it.
Unfortunately it doesn't happen and you have C# , not C##
so you need to invent some strange things:
1. Checker class:
void F(A a)
{
Checker.NotNull(a);
}
2. If you have metaattributes in your language (Nemerle has
) you can write something like this:
F([NotNull] a : A) : void
{
}
And this will produce code as mentioned in 1.
Nullability is a bigger problem then many think about it and .Net didn't solve it elegantly as it could be.
Enjoy.

