兩個部分是:爲什麼靜態類不能有析構函數?
如果一個靜態類可以有靜態構造函數,爲什麼不能有一個靜態的析構函數?
什麼是最好的解決方法?我有一個靜態類來管理COM對象的連接池,如果程序中的其他地方出現問題,我需要確保它們的連接被關閉/釋放。
兩個部分是:爲什麼靜態類不能有析構函數?
如果一個靜態類可以有靜態構造函數,爲什麼不能有一個靜態的析構函數?
什麼是最好的解決方法?我有一個靜態類來管理COM對象的連接池,如果程序中的其他地方出現問題,我需要確保它們的連接被關閉/釋放。
而不是一個靜態類,你應該使用一個普通類與單例模式(即,你保持類的一個單一實例,可能由類本身的一個靜態屬性引用)。那麼你可以有一個析構函數,或者甚至更好,一個析構函數和Dispose方法的組合。
例如,如果你現在有:
static class MyClass
{
public static void MyMethod() {...}
}
//Using the class:
MyClass.MyMethod();
你將不得不改爲:
class MyClass : IDisposable
{
public static MyClass()
{
Instance=new MyClass();
}
public static MyClass Instance {get; private set;}
public void MyMethod() {...}
public void Dispose()
{
//...
}
~MyClass()
{
//Your destructor goes here
}
}
//Using the class:
MyClass.Instance.MyMethod();
(注意實例是如何在靜態構造函數,調用第一次創建任何類的靜態成員被引用)
1.爲什麼? -類型不能像本質上通常考慮實例上的構造函數那樣擁有構造函數。通常,它有時被稱爲「靜態初始化器」方法,但Microsoft使用術語「類型構造器」(並且它有特殊的限制) - 您將代碼放入其中以初始化類型/類 - 如果它是一個實例構造器,它可能是超載。這種對「類型構造函數」的靜態限制是因爲.NET CLR負責在堆上加載類模板,並且不允許在這種情況下指定參數(因爲您將如何傳遞參數)。因爲從最嚴格的意義上說,程序員並不負責引起類型構造函數被調用,所以當程序員在CLR的域中更多時允許程序員編寫靜態析構函數是沒有多大意義的。 CLR最終將從堆中移除類模板,但類模板的生命週期比其實例長,因此無論如何您都不希望進行任何資源密集型操作(例如,保持打開數據庫連接)。
2.什麼? - Singleton 如果您遇到需要在類模板上打開資源並在之後銷燬它的情況,則可以考慮Singleton software pattern只有該類的一個實例,並且可能還實現了System.IDiposable接口除了析構函數之外,還有幫助清理。 (我看到有人已經先打我的IDisposable代碼示例,所以我會在這裏結束我的解決方案。)
靜態類沒有析構函數,因爲一個靜態類永遠不會被破壞。
如果你想創建和銷燬它的多個實例,它不應該是靜態的。讓它成爲一個完整的課程。
無論如何不應該使用析構函數來達到這個目的。使用IDisposable/Dispose。
爲什麼編譯器允許你有一個? 'static〜ClassName(){}'它是否永遠不會運行? – Zapnologica
靜態類永遠不會被破壞。它與程序一起終止。您可以使用單例模式作爲實現,而不是使用靜態類
您確定某個類(類型)沒有垃圾回收嗎? –
@HenkHolterman是的。沒有什麼可收集的。由於所有的屬性/字段至少有一個引用(靜態類),並且由於靜態類的範圍是從第一次訪問直到程序終止,所以沒有任何東西可以收集 –
謝謝。我還在我的代碼中添加了一個私有的非靜態構造函數,因此該類不能在其他地方實例化。 –
如果使用線程,則需要使代碼線程安全。 –
這裏有一個很好的指導,介紹所有不同的方式來執行單線程模式與線程安全。 http://csharpindepth.com/Articles/General/Singleton.aspx – Naz