Lazy<T> with implicit cast to T can give you some pretty code

Adding an implicit cast functionality to Lazy<T> can give you an option to writing null checkers in your delayed instantiation properties.

The problem

Today in our project a colleague was cussing over the fact that he kept writing the same block of code over and over again when null checking a property with a backing field.

Given the class Foo:

private Foo oldFooProp;
public Foo OldFooProp
{
    get 
    {
        if (oldFooProp == null)
        {
            oldFooProp = new Foo();
        }
        return oldFooProp;
    }
}

Have any of you written something like this before? It’s a bunch of lines of code that you tend to write (in small variations) over and over again. Sure you can compact it a little but it in the order of 5 – 10 lines of annoying repetitive code.

Some use the null coalescing operator (??) version that looks like this:

public Foo OldAlternativeFooProp
{
    get
    {
        return oldFooProp ?? (oldFooProp = new Foo());
    }
}

This version is a little easier to compact down to even a single line.

But we (my colleague and I) can do you one better:

Here is an optional approach

private Lazy<Foo> foo = new Lazy<Foo>();

public Foo Foo
{
    get
    {
        return foo;
    }
}

Actually I’d prefer to do that like this but then you have to know the solution below and be comfortable with it:

public readonly Lazy<Foo> Foo = new Lazy<Foo>();

But wait a minute: That doesn’t work you say, right? You can’t return a Lazy<Foo> as a Foo you have to write theFoo.Value.

The Trick

The secret trick is to inherit Lazy<T> and implement an implicit operator for T on it!

namespace Jayway.com.Sys
{
    /// <summary>
    /// A version of <see cref="Sys.Lazy{T}"/> with the twist of being implicitly castable to <typeparamref name="T"/>.
    /// </summary>
    /// <typeparam name="T">The type of lazy instance we are creating.</typeparam>
    public class Lazy<T> : System.Lazy<T>
    {
        // Ctors removed for brevity
/// <summary> /// Cast the <see cref="Lazy{T}"/> to it's contained <typeparamref name="T"/> /// </summary> /// <param name="lazyT">The lazy to cast.</param> /// <returns>The instance of <see cref="Lazy{T}.Value"/></returns> public static implicit operator T(Lazy<T> lazyT) { return lazyT.Value; } } }

Now you can implicitly cast a Lazy<T> to it’s contained type T.

A few alternative constructions for it might look like this:

public LazyTests()
{
    // With parameter
    theFoo = new Lazy<Foo>(() => new Foo("bar"));

    // With Inversion Of Control
    IServiceLocator serviceLocator = GetServiceLocator();
    theFoo = new Lazy<Foo>(() => serviceLocator.GetInstance());
}

I kind of like this code. It’s compact. It’s easy to read. It’s pretty!

Hope you like it too – HTH!

Cheers,

M.

Technorati Tags: ,

posted @ Thursday, August 05, 2010 9:57 PM

Print

Comments on this entry:

No comments posted yet.

Your comment:



 (will not be displayed)


 
 
 
Please add 6 and 8 and type the answer here:
 

Live Comment Preview: