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 处理。

我被困住了!:)

4

1 回答 1

1

您可以使用弱引用。这允许您维护所有管理器的列表,而不会影响垃圾收集。

但是,在这种情况下使用泛型有一些缺点。该类SpecialContextManager可以强制转换为ContextManager<SpecialContext>. 没关系。但是,此类不能转换为ContextManager<ContextBase>,因为它们是两个不同的类。因此,您不能调用 RegisterInstance(ContextManager<ContextBase>)传递一个具体的经理。因此,您可以将objects(或)存储WeakReferencesobjects列表中,也可以采用不同的方法(例如,通过反射获取所有类)。但话又说回来,检索所有管理器的方法的返回类型必须是object某种方式。

于 2013-06-13T11:08:04.173 回答