我一直在寻找进行延迟初始化的方法,发现.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/

10-11 20:25