There is
no-doubt that the C#2 nullable-types
is a cool feature. However I regret that C# don’t support the other
half of the paradigm: the non-nullable types.
The same
way as nullable-types allow null values for value-types, non-nullable types forbid
null references for reference types. In
the following example the method AcceptNonNullString(string!) takes a non-nullable
string as parameter.
static void AcceptNullString(string
s) {
AcceptNonNullString(null);
// <- Here the compiler emit an error.
AcceptNonNullString(s); // <- Here the
compiler emit an error
// because ‘s’ might
be null.
}
static void AcceptNonNullString(string!
s) {
// Here we have
the garantee that the reference ‘s’ is not null.
int length =
s.Length;
}
The !
syntax comes from the an extension of C# named Spec# .
I think it is an elegant and
concise syntax that allows to get rid of a problem
programmers face every day: NullReferenceException. This power comes at a
cost. There exist some cases where the compiler should be tweaked in order to
ensure the non-nullable condition, for example:
- ·
There
is problem to check non-nullable instance fields:
public class Foo {
string! m_String;
public Foo(string! s) {
// Here the
compiler must understand that m_String
// hasn’t
been assigned yet and is null.
int
length = m_String.Length;
m_String = s;
}
}
- ·
There is problem to check
non-nullable static fields:
public class Foo {
static string! s_String;
static
Foo() {
// Here the
compiler must understand that s_String
// hasn’t
been assigned yet and is null.
int
length = s_String.Length;
s_String = “hello”;
}
}
- ·
There
is problem to check arrays of non-nullable elements:
void Method() {
string![]
array = new string![2];
// Here array[0]
and array[1] are null references.
array[0] = “hello”;
array[1] = “hello”;
}
More information
on these problems can be found here on these excellent blog posts [1] [2] [3] [4] by Cyrus Najmabadi, a software design
engineer on the C# team.
I had the
chance during the last MVP summit in March 2007 to talk about non-nullable
types with the C# team. It seems that the biggest hindrance to the adoption of non-nullable
types is that it is so powerful that it would disturb programmers’ habits
and code base. Indeed, we agreed that something like 70% of references of C# programs are likely to end-up as non-nullable ones. This underlines the fact
that null references are the exception and not the rule.Indeed, null
references is a trick inherited from the good old days with C++. Nowadays, programmers
are used to rely on null references to avoid writing too much
code for simple check such as field not initialized or optional parameters. The NullReferenceException problem is a high price to pay for this facility.
In this
context, adding the ! syntax to C# is a bit awkward since the vast majority
of references would use this extra syntax. Personally, I could live with
that. We now don’t have the choice. We spend our time inserting numerous
non-null checks and asserts in our methods and we pray that it is
enough to avoid the pesky NullReferenceException experience to our users. It is
never too late to do things well and non-nullable types should be added to C#4
(it is clearly too late to add such a feature to C#3).