2016-04-30 79 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 
    } 
}