Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does trying to access a property of null cause an exception in some languages?

The thing that really bothers me the most about some programming languages (e.g. C#, Javascript) is that trying to access a property of null causes an error or exception to occur.

For example, in the following code snippet,

foo = bar.baz;

if bar is null, C# will throw a nasty NullReferenceException and my Javascript interpreter will complain with Unable to get value of the property 'baz': object is null or undefined.

I can understand this, in theory, but in real code I often have somewhat deep objects, like

foo.bar.baz.qux

and if any among foo, bar, or baz is null, my codes are broken. :( Further, if I evaluate the following expressions in a console, there seem to be inconsistent results:

true.toString() //evaluates to "true"
false.toString() //evaluates to "false"
null.toString() //should evaluate to "null", but interpreter spits in your face instead

I absolutely despise writing code to handle this problem, because it is always verbose, smelly code. The following are not contrived examples, I grabbed these from one of my projects (the first is in Javascript, the second is in C#):

if (!(solvedPuzzles && 
      solvedPuzzles[difficulty] && 
      solvedPuzzles[difficulty][index])) {
      return undefined;
   }
return solvedPuzzles[difficulty][index].star

and

if (context != null &&
   context.Request != null &&
   context.Request.Cookies != null &&
   context.Request.Cookies["SessionID"] != null) 
{
   SessionID = context.Request.Cookies["SessionID"].Value;
}
else
{
   SessionID = null;
}

Things would be so much easier if the whole expression returned null if any one of the properties was null. The above code examples could have been so much simpler:

return solvedPuzzles[difficulty][index].star;
    //Will return null if solvedPuzzles, difficulty, index, or star is null.

SessionID = context.Request.Cookies["SessionID"].Value;
    //SessionID will be null if the context, Request, Cookies, 
    //Cookies["SessionID"], or Value is null.

Is there something I'm missing? Why don't these languages use this behavior instead? Is it hard to implement for some reason? Would it cause problems that I'm overlooking?

like image 836
Peter Olson Avatar asked Aug 08 '11 15:08

Peter Olson


1 Answers

Would it cause problems that I'm overlooking?

Yes - it would cause the problem where you expect there to be non-null values, but due to a bug, you've got a null value. In that situation you want an exception. Failing silently and keeping going with bad data is a really bad idea.

Some languages (such as Groovy) provide a null-safe dereference operator which can help. In C# it might look something like:

SessionID = context?.Request?.Cookies?["SessionID"]?.Value;

I believe the C# team have considered this in the past and found it problematic, but that doesn't mean they won't revisit it in the future of course.

like image 119
Jon Skeet Avatar answered Oct 05 '22 19:10

Jon Skeet