But I only just realized that extension methods are cool for avoiding NullReferenceExceptions.

We all know that if you have something like this:

LicensePlate licensePlate = null;
Car car = licensePlate.Car;

It will throw a NullReferenceException. However if you have an extension method

public static Car GetCar(this LicensePlate lp);

we can call it like this:

Car car = licensePlate.GetCar();

And we can still handle the fact that 'licensePlate' is null gracefully. i.e.

public static Car GetCar(this LicensePlate lp)
{
    if (lp == null) return null;
    return lp.Car;
}

Now imagine you wanted to chain a whole series of calls something like this:

string code = licensePlate.Car.Owner.Address.PostCode;

That is incredibly unsafe, because any one of those properties could potentially return null.

To get around that you could use a general purpose extension method using generics, to allow you to go through a set of arbitrary translations, anyone of which could do nasty things like return null:

public static V Maybe<T, V>(this T t, Func<T, V> selector)
            where T : class
           
where V : class
{
    if (t == null) return null;
    return selector(t);
}


Now you can use this to chain a whole load of unsafe methods together.

string code = licensePlate.Maybe(lp => lp.Car)
                          .Maybe(c => c.Owner)
                          .Maybe(o => o.Address)
                          .Maybe(a => a.PostCode);

It looks a lot like the Maybe monad (hence the name). The interesting thing though, is that if you implement your methods as extensions methods rather than instance methods, you can wire this sort of thing in so easily, without needing to use lambdas at all.

i.e. so rather than this which is unsafe:

string code = licensePlate.Car.Owner.Address.PostCode;

of this which is ridiculously cumbersome and hard to read:

LicensePlate licensePlate = null;

Car car = null;

Person owner = null;

Address address = null;
string
code = null;

if (licensePlate != null)
{
    car = licensePlate.Car;
    if (car != null)
    {
        owner = car.Owner;
        if (owner != null)
        {
            address = owner.Address;
            if (address != null)
            {
                code = address.PostCode;
            }
        }
    }
}

or this which is a little complicated for anyone uncomfortable with lambdas:

string code = licensePlate.Maybe(lp => lp.Car)
                          .Maybe(c => c.Owner)
                          .Maybe(o => o.Address)
                          .Maybe(a => a.PostCode);

you could write this:

string code = licensePlate.GetCar().GetOwner().GetAddress().GetPostCode();

Which is almost as easy to read as the original version. But much safer.

All you have to do is write your extension method to handle nulls.

Sometimes the coolest things are right under your nose.