(Non)Nullable Types in C# 2.0

Eric Gunnerson blogged last week about Nullable types in C# 2.0. This new C# feature will allow one to specify a Type like int? which will act just like a regular int, with the exception that it can now also be null. The "?" syntax comes from this Microsoft Research paper, which introduces the following Regex-inspired Type-modifiers:

Type*Zero or more of Type
Type+One or more of Type
Type?Zero or One of Type
Type!Exactly One of Type

In .NET, by definition a value type defaults to "!" (i.e. is not nullable) while a reference type defaults to "?" (i.e. is nullable).

With the introduction of "?" in C# 2.0, developers will be able to override the default value type behavior, which is interesting and useful, but the one I'd really like to see implemented would be "!" on a reference type. Being able to protect against NullReferenceExceptions at compile-time would be a very powerful construct, helping both program readability as well as robustness. Methods would no longer have to check if their parameters are non-null while callers would know whether it's ok to pass in a null in the first place. Also, when calling a method, you would be assured the returned object would always be non-null.

The assignment rules would be simple enough:

Type nullable = ...;
Type! nonNullable = ...;
nullable = nonNullable; // compiles fine
nonNullable = nullable; // fails compilation
nonNullable = (Type!)nullable; // compiles but may throw a NullReferenceException at runtime
The main problem with introducing "!" into the existing .NET framework would be that it can't really be integrated in the existing libraries. Method return-types can be changed to "!" notation without any problems (as they're assignment compatible to existing types), but changing method arguments that way would break almost all code currently using that method.

A potential solution to this problem would be allow for another modifier or keyword ("Type!?" maybe?) that would allow assignments from regular reference-typed objects at compile-type, but that compiles into code that checks for null at runtime and possibly throws a NullReferenceException. Apart from assignment, variables of this type would behave just like "Type!" as its value will be guaranteed to be non-null. In doing this, we would not gain the compile-time checking advantage (as the backwards compatibility sacrifice would simply be too large), but we'd still gain in readability and maintainability as the code would become more self-documenting.

There is of course another solution, which would be to simply leave the current framework method parameters as-is, but I think the enhanced self-documenting nature and automatic early null-checks of using a method argument modifier would be preferable. Also, even though we cannot get the compile-time checking, we certainly can have the compiler spit out warnings when regular (nullable) types are passed as arguments to these methods.

TrackBack URL for this entry: http://www.hutteman.com/scgi-bin/mt/mt-tb.cgi/144
Comments

Check out the code I posted to Eric's discussion forum. While we don't get all the way there, we do get a bit of the way. It creates a template nonnull - so you can do the following:

void ShowMessageBox( nonNull message)
{MessageBox.Show( message );}

void Example() {ShowMessageBox("Hello world");}

and you are absolutely guaranteed that function will never throw an argument null exception! It's even better with return types - you just return nonNull, and then return whatever, and it's guaranteed to come out non-null.

Posted by darren oakey at June 3, 2004 12:47 AM

Non-nullable reference types are something I've wanted to see in Java for a long time...

Posted by Robert Lowe at June 3, 2004 9:20 AM

Robert, Nice provides this behaviour for JVM, with use of standard libraries.

void main(String[] args){  
   ?String nullable = null;
   String nonNullable = "nonNullable";
   nullable = nonNullable;
   nonNullable = nullable;
}

\test\test.nice: line 5, column 4:
The value nullable cannot be assigned to nonNullable because it might be null.

To allow nonNullable to contain the null value, it should be declared as:
?java.lang.String nonNullable
nonNullable = notNull(nullable);




See
Nice language, Option types
Autoboxing and NullPointerExceptions in Java 1.5


Posted by Isaac Gouy at June 3, 2004 11:33 AM

Darren: yes, I saw the code you posted on Eric's blog, but see the following problems with it:


  • Because it's not integrated in the language, there's no way to do any compile-time checks on (non-)nullability, which is where IMHO the real payoff would be.

  • Syntax-wise it's a bit more cumbersome than just being able to declare something as TheType!.
  • Because it's a custom add-on, no framework methods will return NonNulls.
  • Since NonNull is a class, there's nothing stopping someone from doing something like
    "NonNull<String> s = null;", which kind of defeats the purpose of what you're trying to achieve. Making NonNull a struct should fix this issue I guess...


So while you can "kind-of" get non-null-functionality with an approach like that, I don't see it catching on or being truly useful until it gets integrated in the framework itself.

Posted by Luke Hutteman at June 3, 2004 1:06 PM

re: Who wants non-nullable types (I do, I do!)?

Trackback from Cyrus' Blather at June 3, 2004 3:42 PM

Who wants non-nullable types (I do, I do!)?

Trackback from Cyrus' Blather at June 3, 2004 4:37 PM

Who wants non-nullable types (I do, I do!)?

Trackback from Cyrus' Blather at June 3, 2004 5:44 PM

Custom Attributes

Trackback from Anderson on... at July 15, 2004 11:24 AM

Strongly agree with you here. But this is just syntactic sugar for what should already be part of the type system . First we need a Nonnull class, or something like that (a better name needed of course), then the type! is just sugar :)

Posted by Aaron at January 26, 2006 7:18 PM
This discussion has been closed. If you wish to contact me about this post, you can do so by email.