正如我在另一个答案的评论中所说,对 ref 参数的需求是代码异味。首先,如果你在一个方法中这样做,你就打破了单一责任原则,但更重要的是,代码只能在你的继承层次结构中重用。
这里有一个模式可以推导出来:
public class LazyInit<T>
where T : class
{
private readonly Func<T> _creationMethod;
private readonly object syncRoot;
private T _instance;
[DebuggerHidden]
private LazyInit()
{
syncRoot = new object();
}
[DebuggerHidden]
public LazyInit(Func<T> creationMethod)
: this()
{
_creationMethod = creationMethod;
}
public T Instance
{
[DebuggerHidden]
get
{
lock (syncRoot)
{
if (_instance == null)
_instance = _creationMethod();
return _instance;
}
}
}
public static LazyInit<T> Create<U>() where U : class, T, new()
{
return new LazyInit<T>(() => new U());
}
[DebuggerHidden]
public static implicit operator LazyInit<T>(Func<T> function)
{
return new LazyInit<T>(function);
}
}
这使您可以这样做:
public class Foo
{
private readonly LazyInit<Bar> _bar1 = LazyInit<Bar>.Create<Bar>();
private readonly LazyInit<Bar> _bar2 = new LazyInit<Bar>(() => new Bar("foo"));
public Bar Bar1
{
get { return _bar1.Instance; }
}
public Bar Bar2
{
get { return _bar2.Instance; }
}
}