2016-04-30 41 views

回答

0

如果你看看摘要问题的两个构造...

// Summary: 
//  Provides support for lazy initialization. 
// 
// Type parameters: 
// T: 
//  Specifies the type of object that is being lazily initialized. 
public class Lazy<T> { 
    // Summary: 
    //  Initializes a new instance of the System.Lazy<T> class. When lazy initialization 
    //  occurs, the default constructor of the target type is used. 
    public Lazy(); 
    // 
    // Summary: 
    //  Initializes a new instance of the System.Lazy<T> class. When lazy initialization 
    //  occurs, the specified initialization function is used. 
    // 
    // Parameters: 
    // valueFactory: 
    //  The delegate that is invoked to produce the lazily initialized value when 
    //  it is needed. 
    // 
    // Exceptions: 
    // System.ArgumentNullException: 
    //  valueFactory is null. 
    public Lazy(Func<T> valueFactory); 
} 

这就是说,主要的区别是,你能做些什么类型的第二个构造

如。 ...

new Lazy<Foo>(() => new Foo(){ SomeProperty = someValue}); 

new Lazy<Foo>(() => new Foo(someValue)); 

......这与默认的构造函数不同。

此外,如果该类型没有默认构造函数而没有参数,则new Lazy<T>()可能会失败。

+1

没关系,这是一个愚蠢的问题的答案就在问题本身 – Jack

2

从我的理解你会使用lambda表达式的形式,当你想传递参数在初始化中使用。我不认为没有参数的lambda有用例。

+0

待NIT挑剔,反射创建对象的实例比执行更慢一个lambda来构造实例。当然,根据你的用例,它可能根本不重要,但某个地方的某个人可能会有一个用例。 –

+0

我同意但是(有点)讽刺的是,不是5分钟前我刚刚看到这个链接的另一个问题,你的评论让我想起了它。 [Performance Rant](https://ericlippert.com/2012/12/17/performance-rant/) –

2

new Lazy<Foo>()使用反射来创建一个Foo的实例,使用类似下面的代码Activator.CreateInstance(typeof(T))来调用默认构造函数。这意味着Foo必须具有默认构造函数。

另一方面,如果需要,Lazy<Foo>(Func<T>)为您构建通过Lazy类型创建的实例提供了更大的灵活性。

1

当类型可以使用默认构造函数实例化时,默认的Lazy构造函数很有用。这意味着new Lazy<Foo>(() => new Foo()),其中Foo不采用构造参数,在大多数情况下可简化为new Lazy<Foo>()

例外是当类型的构造函数是私有的 - 因为如前所述默认的Lazy<T>构造函数使用Activator.CreateInstance(typeof(T)),如果构造函数是私有的,即使它没有参数,这也不起作用。例如,如下一个可能实现使用Lazy<T>单身:

public class Foo 
{ 
    // Notice that the Lazy(Func<T>) constructor is used here 
    // because Foo's constructor is private 
    private static readonly Lazy<Foo> _instance = new Lazy<Foo>(() => new Foo()); 
    public static Foo Current => _instance.Value; 

    private Foo() 
    { 
     // Don't allow calling code to new 
    } 
}