2013-02-06 18 views
7

我所經歷的Edulinq由Jon飛碟雙向,和我遇到下面的代碼,第23頁,他在其中實現緩存機制Empty()運營商的LINQ喬恩斯基特的Edulinq - 空數組緩存

private static class EmptyHolder<T> 
{ 
    internal static readonly T[] Array = new T[0]; 
} 

我的問題來了是,這是如何緩存Array變量的?

(可選)在CLR中它是如何工作的?

編輯:此後,他提到了反對返回數組的反抗。爲什麼不應該返回一個數組(即使它是0大小?)?

+0

Array'的'值後保存應用程序的生命週期'EmptyHolder '是第一因爲它是靜態的。 – Matthew

回答

12

我的問題是,這是如何實際緩存數組變量?

CLR通過類型參數對其進行緩存。基本上,EmptyHolder<int>是與EmptyHolder<string>等不同的類型,並且類型初始值設定項會根據具體類型(由CLR自動調用)調用一次。

所以:

var x = EmptyHolder<string>.Array; // Needs to construct the empty string[] array 
var y = EmptyHolder<string>.Array; // No extra work! x and y have the same value 
var z = EmptyHolder<int>.Array; // This constructs an empty array for int[] 

可選的,它是如何在CLR工作?

這是一個我不太瞭解的實現細節,恐怕。但基本上這是所有有關CLR如何做的事情:)

編輯:也緊接着,他提到有反對回到數組的反叛。爲什麼不應該返回一個數組(即使它是0大小?)?

嗯,有一個評論:

的陣列方法是沒有那麼大:人們會錯誤地依賴於返回值是一個數組,雖然這不是記錄。

個人而言,我不認爲這是一個問題,但它是好玩寫的另一種實現:)

0

每次您爲T第一次調用EmptyHolder.Empty()時,您都必須調用EmptyHolder的靜態構造函數。

現在看起來好像沒有靜態構造函數,對吧?錯誤。該類可以被重寫爲...

private static class EmptyHolder<T> 
{ 
    static EmptyHolder<T>() 
    { 
     Array = new T[0]; 
    } 
    internal static readonly T[] Array; 

    public IEnum<T> Empty(); 
} 

現在,後續運行的Empty將不會調用靜態構造函數(除非使用不同的T)。

無論如何,我可能會批評Jon Skeet,這是一個需要擔心的微小優化。

+2

(對不起之前沒有評論 - 我以前沒有見過這個問題。)他們不一樣。這段代碼有一個靜態構造函數;我的代碼沒有。兩者都有類型初始值設定項,但這不是一回事。它會影響性能,有什麼樣的時間保證。 http://csharpindepth.com/Articles/General/Beforefieldinit.aspx –