2013-01-21 69 views
2

我在我的C#程序,它包含一個靜態成員,屬於該類別的所有實例的字典收集了一堆類的集合實例 - 這樣的事情:基類來保存派生類

class A 
{ 
    private static Dictionary<int,A> dict = new Dictionary<int, A>(); 
    public static A GetInstance(int handle) { return dict[handle];} 

    public A(int handle) {this._handle = handle; dict[handle] = this;} 
    ~A() { dict.Remove(_handle);} 
    private int _handle; 

} 

我已經在一些類中重複了這個,並且想要將這個通用代碼分解出來,但無法弄清楚這是如何實現的。把它放到一個普通的基類中是行不通的,因爲我想爲每個具體類創建一個新的集合。我覺得必須有一種方法可以用泛型來實現,但目前我還不太明白。

例如,這是不正確的:

abstract class Base<T> 
{ 
    private static Dictionary<int,T> dict = new Dictionary<int, T>(); 
    public static T GetInstance(int handle) { return dict[handle];} 

    public A(int handle) {this._handle = handle; dict[handle] = this;} 
    ~Base() { dict.Remove(_handle);} 
    private int _handle; 
} 

class A : Base<A> 
{ 
} 

它沒有請編譯爲A的構造是不正確的。我在這裏錯過了一招嗎?

+4

不要這樣做;這是內存泄漏。你的finalizer永遠不會運行。 (並且你不應該使用終結器) – SLaks

+0

@SLaks這可以通過'IDisposable'實現而不是終結器來實現嗎? – horgh

+0

@KonstantinVasilcov:這仍然是一個壞主意。 – SLaks

回答

2

這是使用IDisposable interface實現我的變種:

class Base<T> : IDisposable 
    where T : Base<T>, new() 
{ 
    private static Dictionary<int, T> dict = new Dictionary<int, T>(); 
    private static T Get(int handle) 
    { 
     if (!dict.ContainsKey(handle)) 
      dict[handle] = new T(); //or throw an exception 
     return dict[handle]; 
    } 
    private static bool Remove(int handle) 
    { 
     return dict.Remove(handle); 
    } 

    public static T GetInstance(int handle) 
    { 
     T t = Base<T>.Get(handle); 
     t._handle = handle; 
     return t; 
    } 

    protected int _handle; 

    protected Base() { } 

    public void Dispose() 
    { 
     Base<T>.Remove(this._handle); 
    } 
} 

class A : Base<A> { } 

而且使用它,那麼:

using (A a = Base<A>.GetInstance(1)) 
{ 

} 

在這裏,你沒有public構造任何從Base<T>派生的類。儘管應該使用靜態工廠GetInstance方法來創建實例。請記住,只有在調用Dispose方法時纔會從字典中刪除實例,因此您應該使用using statement或手動撥打Dispose

不過我猜你還是應該考慮SLaks的評論。