我正在寻找实现延迟初始化的方法,并发现了包含在.NET 4中的Lazy<T>
。
我想为.NET 3.5自己实现一个Lazy<T>
(使用更简单的多线程策略),但遇到了以下问题:
Lazy<T>
基本上有两种类型的构造函数:
class Lazy<T> {
public Lazy(){...} // ctor #1
它使用 T 的默认构造函数来创建 T 的实例,而
public Lazy(Func<T> func){...} // ctor #2
这里涉及到了一个让调用者决定T实例创建方式的问题。
现在问题来了:
如果我想对第一个构造函数进行编译时检查,我需要添加一个限制条件。
class Lazy<T> where T: new() {...}
在类级别上设置限制,这样我就可以使用
new T()
来创建一个实例;但是这个限制对于第二个构造函数来说并不是必要的,更糟糕的是,它还限制了我可以使用的类型(只能使用具有默认构造函数的类型)。如果我想要使用任何类型来使用第二个构造函数,我将不设置任何限制,并且在第一个构造函数中将使用反射确保
T
确实具有默认构造函数。然而,这种方法将缺乏编译时检查,只有在使用错误的类型时才会抛出运行时异常。我的问题是:我能否兼顾两全?
理想情况下,我希望在使用构造函数#1时获得编译时检查,但同时也能够使用构造函数#2来处理没有默认构造函数的类型。
微软的实现是如何做到的?(我没有立即访问.NET 4源或dlls)。
编辑:(在“反编译”MS程序集后)
我检查了参考实现,它没有进行编译时检查。
当然,在“默认构造函数”情况下,它使用反射,如果出现问题,则会伴随运行时异常。