2013-06-13 132 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