Cached Property: Easier way?

I have a object with properties that are expensive to compute, so they are only calculated on first access and then cached.

 private List<Note> notes;
 public List<Note> Notes
    {
        get
        {
            if (this.notes == null)
            {
                this.notes = CalcNotes();
            }
            return this.notes;
        }
    }

I wonder, is there a better way to do this? Is it somehow possible to create a Cached Property or something like that in C#?


Solution 1:

As far as syntax goes, you can use the null-coalescing operator if you want to be fancy, but it's not necessarily as readable.

get
{
    return notes ?? (notes = CalcNotes());
}

Edit: Updated courtesy of Matthew. Also, I think the other answers are more helpful to the question asker!

Solution 2:

In .NET 3.5 or earlier, what you have is a very standard practice, and a fine model.

(Although, I would suggest returning IList<T>, or IEnumerable<T> if possible, instead of List<T> in your public API - List<T> should be an implementation detail...)

In .NET 4, however, there is a simpler option here: Lazy<T>. This lets you do:

private Lazy<IList<Note>> notes;
public IEnumerable<Note> Notes
{
    get
    {
        return this.notes.Value;
    }
}

// In constructor:
this.notes = new Lazy<IList<Note>>(this.CalcNotes);

Solution 3:

Looks pretty standard to me. What you are doing is fine.

Solution 4:

The problem with ?? is that if CalcNotes() returns null then it will not be cached any more. Ditto for value types if for example both 0 and NaN are allowed as property value.

Much better would be an "aspect-oriented" solution, something like Post-Sharp does using attributes and then modifying MSIL (bytecode).

The code would look like:

[Cached]
public List<Note> Notes { get { return CalcNotes(); } }

EDIT: CciSharp.LazyProperty.dll does exactly this!!!