2013-06-13 129 views
1

假設我們有3個不同的組件註冊實例

通用裝配

public abstract class ContextBase 
{ 
} 

public abstract class ContextManager<T> where T: ContextBase 
{ 
    // contains all the context managing logic. 
    public T FindContext() 
    { 
     // ... 
    } 
} 

應用特定組件2:

public class SpecialContext : ContextBase 
{ 
    // custom properties specific to this type of context 
} 

public class SpecialContextManager : ContextManager<SpecialContext> 
{ 
    // inherits most of the logic from its base class but has some 
    // overrides to achieve a slightly different behavior 
} 

應用特定組件3:

public class OtherContext : ContextBase 
{ 
    // custom properties specific to this type of context 
} 

public class OtherContextManager : ContextManager<OtherContext> 
{ 
    // inherits most of the logic from its base class but has some 
    // overrides to achieve a slightly different behavior 
} 

爲抽象通用ContextManager類的動機是,每個ContextManager保持特定的給定類型T.你當然可以對象的靜態集合已經做了像那樣Dictionary> ..但我更喜歡通用的基類方法。

問題 現在我想製作一個GUI來顯示/查找所有上下文。這意味着各種背景。 我不想爲每個應用程序程序集中的每個應用程序編寫GUI。 我正在考慮一個「通用GUI」,它向我展示了所有當前活動的上下文,無論它們是什麼類型(知道該類型雖然在GUI中顯示更詳細的信息會很酷)。我顯然可以使用各自的ContextManager實例查找所有上下文 - 但是如何獲取它們?

這是我想到的(和在惡劣的設計方面拒絕):

public static class CmInstanceMonitor 
{ 
    private static List<ContextManager<ContextBase>> _contextMgrs = new List<ContextManager<ContextBase>>; 

    public static void RegisterInstance(ContextManager<ContextBase> cm) 
    { 
     // probably I should make sure I don't add the same object twice 
     // unfortunately I cannot use the Type yet as this method is invoked 
     // by the base class ctor() :(
     _contextMgrs .Add(cm); 
    } 
} 

這樣我ContextManager可能永遠住,因爲保存一個對它的引用的靜態對象。不是我想要的。並且將一些代碼放入ContextManager終結器中可能不會有任何好處,因爲該對象由於靜態引用而不會被GC'ed。

我被卡住了! :)

回答

1

您可以使用Weak References。這使您可以維護所有管理員的列表,而不會影響垃圾收集。

但是,在這種情況下使用泛型有一些缺點。類SpecialContextManager可以投到ContextManager<SpecialContext>。沒關係。但是,這個類不能轉換爲ContextManager<ContextBase>,因爲這是兩個不同的類。因此,您不能致電 RegisterInstance(ContextManager<ContextBase>)傳遞具體經理。因此,您可以將objects(或WeakReferencesobjects)存儲在您的列表中,或使用其他方法(例如通過反射獲取所有類)。但是,再次,檢索所有管理器的方法的返回類型必須以某種方式爲object