Lazy 实现和.NETgenerics

我一直在寻找延迟初始化的方法,并找到了包含在.NET 4中的Lazy

我正在考虑使用自己的Lazy for .NET 3.5实现(使用更简单的multithreading策略),我遇到了以下问题:

Lazy基本上有两种类型的构造函数:

 class Lazy { public Lazy(){...} // ctor #1 

它使用T的默认构造函数来创建T的实例,和

  public Lazy(Func func){...} // ctor #2 

这让调用者决定如何创建T的实例。

现在问题在于:

如果我想要第一个ctor的编译时检查,我将添加一个限制

 class Lazy where T: new() {...} 

在class级。 这将允许我使用new T()来创建一个实例; 但是这个限制对于第二个ctor来说不是必需的,更糟糕​​的是,它也限制了我可以使用的类型(对于那些有默认ctor的人)

如果我想能够使用任何类型的第二个ctor,我将不会设置任何限制,并在第一个ctor将使用reflection,以确保T确实有一个默认的ctor。 但是,这种方法缺少编译时检查,如果第一个ctor使用了错误的类型,则只会抛出运行时exception。

我的问题是:我可以充分利用这两个世界吗?

理想情况下,我想对ctor#1的每次使用进行编译时检查,但同时能够将ctor#2用于没有默认ctor的类型。

Microsoft实现如何执行此操作? (我不能轻易访问.NET 4源代码或dll)。

编辑:(在“reflection器”MS组件之后)

我检查了参考实现,它没有进行编译时检查。
它使用reflection作为’默认ctor’的情况,当然如果事情变坏则伴随着运行时exception。

我希望内置实现只是简单地使用Activator.CreateInstance 。 我可以想到欺骗这个最简单的方法是使用一个单独的工厂:

 // non-generic factory class with generic methods public static class Lazy { public static Lazy Create() where T : new() { return Create(() => new T()); } public static Lazy Create(Func ctor) { ... } } public class Lazy { ... } 

您可以使用静态工厂方法而不是构造函数的重载:

 public class Lazy { public Lazy( Func f ) { /*...*/ } public static Lazy Default() where R : T, new() { return new Lazy( () => new R() ); } } 

现在,这破坏了(在某种程度上)与.NET 4.0版本的Lazy兼容性,但它确实实现了两种类型的使用的编译时安全性。

你可以通过使Lazy内部构造函数变得更加清晰,并提供一个始终用于创建实例的静态工厂类:

 public static class Lazy { static Lazy Create( Func ) { ... } static Lazy Create( ) where T : new() { ... } } 

为什么不直接下载并行扩展并安装Lazy for 3.5? 直接链接

我的问题是:我可以充分利用这两个世界吗?

没有。

基本上你没有编译时可检查约束。

这样的事情对你有用。 我们在本地代码库中使用了一年左右,然后再迁移到4.0。

 public class Lazy { private Func func; private T result; private bool hasValue; public Lazy(Func func) { this.func = func; this.hasValue = false; } public T Value { get { if (!this.hasValue) { this.result = this.func(); this.hasValue = true; } return this.result; } } }