2010-09-03 64 views
4

我有一個簡單的類,它有一個靜態構造函數和一個實例構造函數。現在,當我初始化類時,調用了靜態和實例構造函數。只有靜態在應用程序域中被引用一次。我可以再次調用相同的類初始化和靜態構造函數初始化嗎?我已經嘗試過,但沒有發生?有沒有什麼辦法可以在類中使用垃圾回收之後,在main()方法中再次調用靜態構造函數。C#靜態垃圾收集器?

下面是代碼:

public class Employee 
{ 
    public Employee() 
    { 
     Console.WriteLine("Instance constructor called"); 
    } 

    static Employee() 
    { 
     Console.WriteLine("Static constructor called"); 
    } 

    ~Employee() 
    { 
     //Dispose(); 
    } 
} 

現在主要方法調用:

static void Main(string[] args) 
{ 
    Employee emp = new Employee(); 
    Employee emp = new Employee(); 
} 

輸出:

靜態構造函數稱爲 實例構造稱爲 實例構造稱爲

現在靜態沒有再次調用。因爲它在應用程序域中被調用一次。但是,他們是否可以在不卸載應用程序域的情況下再次調用它。我們可以在這裏使用GC類嗎?

謝謝。 Pal

+2

爲什麼你在地球上編寫代碼? – 2010-09-03 12:18:12

+1

@Developer:因爲他可以:-D – abatishchev 2010-09-03 12:24:55

+0

@Developer ARt,請告訴我爲什麼我們不能在一個類中有多個靜態構造函數?爲什麼:-D ...? – 2010-09-03 12:31:23

回答

8

除非您使用反射來刺激它,否則靜態構造函數(或更一般地說,類型初始化程序)僅對每個AppDomain的每個具體類執行一次。

需要注意的是仿製藥,使用不同類型的參數,你會得到不同的具體類:

public class Foo<T> 
{ 
    Foo() 
    { 
     Console.WriteLine("T={0}", typeof(T)); 
    } 
    public static void DummyMethod() {} 
} 
... 
Foo<int>.DummyMethod(); // Executes static constructor first 
Foo<string>.DummyMethod(); // Executes static constructor first 
Foo<string>.DummyMethod(); // Type is already initialized; no more output 
2

不可能的。 CLR保持一個內部狀態位,用於跟蹤類型初始值設定項是否啓動。它不能再運行。該狀態位確實存儲在加載程序堆中,作爲AppDomain狀態的一部分。解決方法很簡單,只需向類中添加靜態方法即可。

1

構造函數的要點是將事物放入所需的初始有效狀態。

實例構造函數將實例放入初始有效狀態。

帶參數的實例構造函數將實例放入一個反映其參數的初始有效狀態。

靜態構造函數將類型置於初始有效狀態。例如。初始化類的靜態方法使用的靜態成員或所有實例共享的靜態成員。

理想情況下,所有方法都將使對象和類型處於有效狀態,但構造方法在負責將其置於一個狀態中時有所不同。因此,任何試圖調用構造函數兩次的嘗試都是錯誤的,因爲「再次將其置於初始有效狀態」不是您可以在邏輯上做兩次(「初始」和「再次」不能很好地工作同一條款)。編譯器(它拒絕編譯)和語言(無法表達這一點)幫助我們做這樣的事情。而且,作爲一個邏輯上的不可能性,它並不是你實際上想要做的事情(當然,我可以畫出一個三角形,但只能說我做了)。這表明您正在使用您的構造函數來執行除設置初始有效狀態之外的其他操作。

除了在構造函數中建立這樣的有效狀態之外,做其他任何事情都是(儘量不這樣做)充其量只是最優化,通常是嚴重的設計缺陷,很可能(更糟糕的是,因爲它更長時間不固定)嘗試優化,這是一個嚴重的設計缺陷。

一個跡象表明,您嘗試進行優化實際上是一個設計缺陷,是希望不止一次調用靜態構造函數,或者在同一個對象上多次調用實例構造函數。

確定所需的可重複行爲,將其移動到單獨的方法中,並根據需要從構造函數和其他位置調用它。然後仔細檢查你的設計邏輯,因爲在課堂設計中發現這是一個嚴重的錯誤,並且表明你有更深的問題。