C# Language Avoid Null References


Example

C# developers get a lot of null reference exceptions to deal with. F# developers don't because they have the Option type. An Option<> type (some prefer Maybe<> as a name) provides a Some and a None return type. It makes it explicit that a method may be about to return a null record.

For instance, you can't read the following and know if you will have to deal with a null value.

var user = _repository.GetUser(id);

If you do know about the possible null you can introduce some boilerplate code to deal with it.

var username = user != null ? user.Name : string.Empty;

What if we have an Option<> returned instead?

Option<User> maybeUser = _repository.GetUser(id);

The code now makes it explicit that we may have a None record returned and the boilerplate code to check for Some or None is required:

var username = maybeUser.HasValue ? maybeUser.Value.Name : string.Empty;

The following method shows how to return an Option<>

public Option<User> GetUser(int id)
{
    var users = new List<User>
    {
        new User { Id = 1, Name = "Joe Bloggs" },
        new User { Id = 2, Name = "John Smith" }
    };

    var user = users.FirstOrDefault(user => user.Id == id);

    return user != null ? new Option<User>(user) : new Option<User>();
}

Here is a minimal implementation of Option<>.

public struct Option<T>
{
    private readonly T _value;

    public T Value
    {
        get
        {
            if (!HasValue)
                throw new InvalidOperationException();

            return _value;
        }
    }

    public bool HasValue
    {
        get { return _value != null; }
    }

    public Option(T value)
    {
        _value = value;
    }

    public static implicit operator Option<T>(T value)
    {
        return new Option<T>(value);
    }
}

To demonstrate the above avoidNull.csx can be run with the C# REPL.

As stated, this is a minimal implementation. A search for "Maybe" NuGet packages will turn up a number of good libraries.