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!!!