2010-05-29 125 views
41

將在通用類的靜態構造函數每次傳遞到泛型參數,如這種類型的運行:C#泛型靜態構造函數

class SomeGenericClass<T> 
{ 
     static List<T> _someList; 
     static SomeGenericClass() 
     { 
      _someList = new List<T>(); 
     } 
} 

是否有抽獎背上用這種方法?

回答

52

是的,靜態構造函數將爲每個封閉類類型(指定類型參數時創建的類型)調用一次。請參閱C# 3 specification,§10.12靜態構造函數。

封閉類類型的靜態構造函數在給定的應用程序域中最多執行一次。

和也:

由於靜態構造正好一次爲每個封閉構造類類型執行時,它是執行在不能在被檢查的類型參數的運行時檢查一個方便的地方編譯時間通過約束(§10.1.5)。例如,下面的類型使用靜態構造來執行該類型參數是一個枚舉:

class Gen<T> where T: struct 
{ 
    static Gen() { 
     if (!typeof(T).IsEnum) { 
      throw new ArgumentException("T must be an enum"); 
     } 
    } 
} 

它也是相關的讀取§4.4.2打開和關閉的類型:

在運行時,泛型類型聲明中的所有代碼都是在通過對泛型聲明應用類型參數而創建的封閉構造類型的上下文中執行的。泛型類型中的每個類型參數都綁定到特定的運行時類型。所有語句和表達式的運行時處理總是在封閉類型中發生,而開放類型只在編譯時處理時纔會發生。

每個封閉構造類型都有自己的一組靜態變量,它們不與任何其他封閉構造類型共享。

這個程序,你可以自己運行表明,該靜態構造函數被調用了三次,不只是一次:

public class Program 
{ 
    class SomeGenericClass<T> 
    { 
     static SomeGenericClass() 
     { 
      Console.WriteLine(typeof(T)); 
     } 
    } 

    class Baz { } 

    static void Main(string[] args) 
    { 
     SomeGenericClass<int> foo = new SomeGenericClass<int>(); 
     SomeGenericClass<string> bar = new SomeGenericClass<string>(); 
     SomeGenericClass<Baz> baz = new SomeGenericClass<Baz>(); 
    } 
} 

輸出:

 
System.Int32 
System.String 
Program+Baz 
+0

那是一個靜態類嗎? – 2010-05-29 21:06:21

+5

@Jouke van der Maas,他談到了靜態課程?問題是關於泛型類的靜態構造函數,而不是靜態類... – 2010-05-29 22:39:32

+0

這是既不,所以它仍然適用:) – 2010-05-30 02:25:52

0

是的,泛型類型的靜態成員和構造函數是特定於泛型參數的,並且將針對每種不同類型運行。沒有真正的缺點。將非泛型類重構爲通用類時要小心。

0

是的,它會針對您提供的每種類型運行,因爲對於每種不同的提供類型,您都會獲得單獨的類型。

2

它將工作,而是一個新的將爲您使用的每種類型創建'實例'。