我一直在寻找进行延迟初始化的方法,发现.NET 4中包含的 Lazy<T>
。
我当时正在考虑为.NET 3.5(使用更简单的多线程策略)滚动自己的Lazy<T>
实现,但遇到了以下问题:
懒惰基本上有两种类型的构造函数:
class Lazy<T> {
public Lazy(){...} // ctor #1
它使用T的默认构造函数创建T的实例,以及
public Lazy(Func<T> func){...} // ctor #2
这使调用者可以决定如何创建T的实例。
现在是问题所在:
如果我想在编译时检查第一个ctor,我会添加一个限制
class Lazy<T> where T: new() {...}
在类里面。这将允许我使用
new T()
创建实例;但是此限制对于第二个ctor并不必要,更糟糕的是,它也限制了我可以使用的类型(仅限于具有默认ctor的类型)如果我希望能够与第二个ctor一起使用任何类型,则不会设置任何限制,并且在第一个ctor中将使用反射来确保
T
确实具有默认ctor。但是,这种方法将缺少编译时检查,并且仅当第一个ctor与错误类型一起使用时才会抛出运行时异常。我的问题是:我能同时兼顾两个方面吗?
理想情况下,我想对ctor#1的每次使用都进行编译时检查,但同时也可以对没有默认ctor的类型使用ctor#2。
Microsoft实现如何做到这一点? (我无法随时访问.NET 4源或dll)。
编辑:(“反射” MS程序集后)
我检查了引用实现,但不进行编译时检查。
它在“默认ctor”情况下使用反射,当然,如果情况变坏,则会伴随运行时异常。
最佳答案
为了简化起见,我希望内置实现只使用Activator.CreateInstance<T>
。我能想到的最干净的方法是在一个单独的工厂进行:
// non-generic factory class with generic methods
public static class Lazy {
public static Lazy<T> Create<T>() where T : new() {
return Create<T>(() => new T());
}
public static Lazy<T> Create<T>(Func<T> ctor) { ... }
}
public class Lazy<T> { ... }
关于c# - Lazy <T>实现和.NET泛型,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3462675/