C# 8 and The Future of Null

C# 8 and The Future of Null

The nullable types

If you have been coding C# for a while you have probably come across Nullable types (Microsoft link). A Nullable type is in instance of System.Nullable<T> where T can be any non-nullable value type (such as int, float, bool). An instance of System.Nullable<T> can represent any value of the underlying type T and also null. When declaring Nullable types the ’?’ shorthand is usually used. For example:

int? a = null; // a is an instance of System.Nullable<int>

Naturally this does not apply to Reference Types (instances of classes) since they can always be null, without wrapping them in a System.Nullable. However, in C# 8, the upcoming major version of C#, this is about to change.

Nullable Reference Types

The header above might sound strange, aren’t all reference types nullable? The answer is, yes, they are. However, starting from C# 8, references that are welcome to be null should be clearly marked as such. The way to mark a reference as nullable will be to use the ’?’ shorthand, these new reference types are what will be called Nullable Reference Types. An example:

// NOTE: This code is only valid from C# 8
public string? FindJohnMayReturnNull()
{
  IEnumerable<string> names = GetNames();
  return names.Where(name => name.StartsWith("John").FirstOrDefault(); // Returns null if there is no match
}

public string FindJohnShouldNotReturnNull
{
  IEnumerable<string> names = GetNames();
  return names.Where(name => name.StartsWith("John").FirstOrDefault() ?? string.Empty; // Returns empty string if there is no match
}

Note that I use the word should. It will be possible to compile your code even without using ’?’ to indicate nullable references, but it will give you a warning.

Conclusion

The introduction of Nullable Reference Types will most certainly make parts of the code better by making developers clearly express their intent (should this reference be nullable or not), and it will hopefully increase awareness for when you need to handle possible null values.

I would love to see code where we can avoid situations like this:

public class MyClass
{
  MyClass(ObjectOne o1, ObjectTwo o2, ObjectThree o3)
  {
    if (o1 == null) throw new ArgumentNullException(nameof(o1));
    if (o2 == null) throw new ArgumentNullException(nameof(o2));
    if (o3 == null) throw new ArgumentNullException(nameof(o3)); 
    ...
  }

  public void DoSomething(Param1 p1, Param2 p2)
  {
    if (p1 == null) throw new ArgumentNullException(nameof(p1));
    if (p2 == null) throw new ArgumentNullException(nameof(p2));

    var values = p1.GetValues();
    if (values == null) throw new ArgumentException(...);
  }
}

However, I don’t think the introduction of Nullable Reference Types will completely remove the need for null checks for all references that aren’t declared as nullable. There will most likely be cases where this is still needed, but hopefully we can reduce it, and over time the code will hopefully be both easier to read and more robust.

For more information see this article from Microsoft on the topic.