CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Patrick Smacchia [MVP C#]


I want non-nullable types in C#4

 
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).

 



Comments

Noticias externas said:

At what point do you consider a programming language bloated? I am not talking about libraries that are

# July 25, 2007 2:51 PM

Justin said:

In C++ we call non-nullable references "references" and nullable references "pointers".

I think it's a real shame that .NET didn't adopt this terminology instead of seemingly copying Java.

I've always thought one of the biggest flaws with Java and .NET is the lack of references.

# July 25, 2007 7:49 PM

Patrick Smacchia said:

.NET references are very different than C++ pointers since there is a GC working under the hood. My point is about adding syntactic sugar to C# to avoid NullRefException.

There is a lot of buzz about C# bloat. As a developper I'm really happy to get new powerful syntactic constructs that make my code more concise. As a trainer, I have to admit that beginners   get lost at first sight and it is our job to explain the intentions behind each language feature.  

# July 26, 2007 11:23 AM

Oskar Austegard said:

(Original post:)

+1

# July 26, 2007 1:43 PM

Pulverturm said:

# July 31, 2007 3:28 AM

Isaac Gouy said:

"In this context, adding the ! syntax to C# is a bit awkward since the vast majority of references would use this extra syntax."

Yes, without the need to maintain back compatibility new languages can just take non-nullable as the default and decorate nullable types with ?

See nice.sourceforge.net/manual.html

# August 3, 2007 2:58 PM

Monkeyget said:

I see i'm not the only one to have thought about it. :)

"In c#/java/c++/.. : Nullable parameters should be opt-in instead of opt-out. By default null parameters should create a compilation error if possible or throw an exception. Actually they all should have design by contract built-in the language with a nice (concise) syntax."

programming.reddit.com/.../cw8bs

# August 3, 2007 4:18 PM

Matt said:

Although I agree with you, I really just want an attribute that would essentially inject a null check and throw ArgumentNullException if appropriate for the specified parameter.

[NotNull("foo")]

void NoNullsAllowed(string foo) { ... }

which would essentially compile to be

void NoNullsAllowed(string foo) {

  if(foo == null) {

       throw new ArgumentNullException("foo");

   }

}

which on the surface seems very much the same as NullReferenceException, but there are key differences. I've just grown tired of coding that null check into all my public methods, it's so repetitive.

# August 3, 2007 4:29 PM

John said:

Value types can't be null. You've had non-nullable types since 1.0.

# August 3, 2007 8:34 PM

  Algebaric Data Types again by ?? Tony’s blog ?? said:

Pingback from  &nbsp; Algebaric Data Types again&nbsp;by&nbsp;?? Tony&#8217;s  blog ??

# August 3, 2007 11:42 PM

  Algebraic Data Types again by ?? Tony’s blog ?? said:

Pingback from  &nbsp; Algebraic Data Types again&nbsp;by&nbsp;?? Tony&#8217;s  blog ??

# August 4, 2007 12:25 AM

mind said:

i think you're just defining your function contracts wrong, and therefore assigning blame in the wrong place.

if i've got a function that takes an argument, and say calls a method on that argument, it's trivial, and almost implied, that you can't pass null into that function. whoever is passing null into that call is obviously in the wrong, and is probably doing so because they haven't finalized their code, and wanted to put a placeholder in so that it would compile (and perhaps forgot to take it out down the line). it's not that function's job to check if it was passed a null unless you explicitly define the function as being able to accept a null and doing something suitable (maybe silently ignoring the call).

if you're writing a public api and want to be all hand-holdy, perhaps you can add checks for your exported methods (but what could you do besides just throw an exception), but frankly i'd rather see the null pointer exception and backtrace when i actually execute the code. and i'd rather not have to deal with the compiler complaining because i'm writing some rough code that doesn't actually run yet, and i don't have the value yet.

i think this idea basically comes down to preventing a developer from doing something that they want to do "for their own good". that in no way sits well with me.

# August 4, 2007 1:28 AM

Patrick Smacchia said:

>Value types can't be null. You've had non-nullable types since 1.0.

Do you mean that we should get rid of all classes benefit (GC, inheritance...) and only rely on structure just to avoid the NullReferenceException?

> it's trivial, and almost implied that you can't pass null into that function

My opinion is that nothing is trivial with source code, especially infering some property from reading it. I want the property of my code to be obvious and checked automatically at compile-time.

>it's not that function's job to check if it was passed a null

I always apply defensive code: I don't know who calls me and always check and assert as many things as I can.

>what could you do besides just throw an exception

Get a compiler error that is much more cheaper

>but frankly i'd rather see the null pointer exception and backtrace when i actually execute the code. and i'd rather not have to deal with the compiler complaining because i'm writing some rough code that doesn't actually run yet, and i don't have the value yet

I think that a compiler error is always preferable than a runtime exception.

# August 8, 2007 4:12 PM

Patrick Smacchia [MVP C#] said:

How should your automatic tests behave when they are executing an assertion through System.Diagnostics

# October 10, 2007 1:33 PM

Marcel Popescu said:

Here's a possible solution, until Microsoft implements this in C# proper...

mdpopescu.blogspot.com/.../non-nullable-reference-types-in-c-c-1.html

# November 8, 2007 7:38 AM

Patrick Smacchia [MVP C#] said:

The only way to have bug-free code is to mathematically prove the code. Very few programs in the world

# March 30, 2008 3:23 PM

Finds of the Week - March 30, 2008 » Chinh Do said:

Pingback from  Finds of the Week - March 30, 2008 &raquo; Chinh Do

# April 1, 2008 1:01 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Patrick Smacchia

Patrick Smacchia is a Visual C# MVP involved in software development for over 15 years. After graduating in mathematics and computer science, he has worked on software in a variety of fields including stock exchange, airline ticket reservation system as well as a satellite base station at Alcatel. He's currently a software consultant and trainer on .NET technologies as well as the lead developer of the tool NDepend which provides numerous metrics and caveats on any compiled .NET application. He is the author of Practical .NET2 and C#2, a .NET book conceived from real world experience with 647 compilable code listings. Check out Devlicio.us!