In an attempt to revitalize this blog, I’m going to write a few post on random bits of code that I’ve found useful recently.
The first sample is Lazy<T>. This simple class allows you to delay the initialization of a variable till its first use. This can come in handy if you have a method with many code paths and you’d like to initialize all variables at the start of the method without the overhead of initializing unnecessarily.
Here’s a usage example:
var fileCount = new Lazy<int>(() => Directory.GetFiles(".").Length);
And the class:
public class Lazy<T> { private bool _hasValue; private T _value; private Func<T> _getter; public Lazy(Func<T> getter) { _getter = getter; } public T Value { get { if (!_hasValue) { lock (this) { if (!_hasValue) { _value = _getter(); _hasValue = true; } } } return _value; } } public override bool Equals(object other) { if (Value == null) { return (other == null); } if (other == null) { return false; } return Value.Equals(other); } public override int GetHashCode() { if (Value == null) { return 0; } return Value.GetHashCode(); } public override string ToString() { if (Value == null) { return ""; } return Value.ToString(); } public static implicit operator Lazy<T>(T value) { return new Lazy<T>(() => value); } public static implicit operator T(Lazy<T> value) { return value.Value; } }
Do you have any thoughts on why it appears the .net 4.0 source in reflector doesn’t have any operators defined for System.Lazy?
Hmm… that’s a really good question. My guess would be that it’d be bad practice to have so much going on inside an operator, because anyone looking at the code couldn’t easily tell that something heavy is going on.
For example, overriding the equality operator to be lazy could cause the the following statement take a long time, and without knowing that and then trying to debug it (especially when looking at performance) could be confusing.
if (a == 2)
DoSomething();