Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 注册未知生存期的实例_C#_Design Patterns_Optimization - Fatal编程技术网

C# 注册未知生存期的实例

C# 注册未知生存期的实例,c#,design-patterns,optimization,C#,Design Patterns,Optimization,假设我们有3个不同的程序集 通用组件 公共抽象类ContextBase { } 公共抽象类ContextManager,其中T:ContextBase { //包含所有上下文管理逻辑。 公共T FindContext() { // ... } } 特定于应用程序的程序集2: 公共类SpecialContext:ContextBase { //特定于此类型上下文的自定义属性 } 公共类SpecialContextManager:ContextManager { //继承其基类的大部分逻辑,但

假设我们有3个不同的程序集

通用组件

公共抽象类ContextBase
{
}
公共抽象类ContextManager,其中T:ContextBase
{
//包含所有上下文管理逻辑。
公共T FindContext()
{
// ...
}
}
特定于应用程序的程序集2:

公共类SpecialContext:ContextBase { //特定于此类型上下文的自定义属性 } 公共类SpecialContextManager:ContextManager { //继承其基类的大部分逻辑,但有一些 //重写以实现稍微不同的行为 } 特定于应用程序的程序集3:

public类OtherContext:ContextBase
{
//特定于此类型上下文的自定义属性
}
公共类OtherContextManager:ContextManager
{
//继承其基类的大部分逻辑,但有一些
//重写以实现稍微不同的行为
}
抽象泛型ContextManager类的动机是,每个ContextManager都保留一个特定于给定类型T的对象的静态集合。当然,您可以执行类似Dictionary>的操作。。但我更喜欢通用基类方法

问题 现在我想制作一个GUI来显示/查找所有上下文。这意味着各种语境。 我不想为每个应用程序集中的每个应用程序编写GUI。 我想到了一个“通用GUI”,它向我显示所有当前活动的上下文,不管它们是什么类型(虽然在GUI中显示一些更详细的信息,但知道它们的类型会很酷)。很明显,我可以使用相应的ContextManager实例找到所有的上下文,但是如何掌握它们呢

这就是我的想法(并因设计不好而被拒绝):

公共静态类CmInstanceMonitor
{
私有静态列表_contextMgrs=新列表;
公共静态无效注册表状态(ContextManager cm)
{
//也许我应该确保不添加同一个对象两次
//不幸的是,在调用此方法时,我还不能使用该类型
//通过基类ctor():(
_contextMgrs.Add(cm);
}
}
这样,我的ContextManager可能永远存在,因为静态对象保存了对它的引用。这不是我想要的。而且,将一些代码放入ContextManager终结器可能不会有任何好处,因为静态引用不会对对象进行GC

我卡住了!:)

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

然而,在这种情况下,使用泛型有一些缺点。类
SpecialContextManager
可以强制转换为
ContextManager
。那很好。但是,此类不能转换为
ContextManager
,因为它们是两个不同的类。因此,你不能打电话
RegisterInstance(ContextManager)
传递一个具体的管理器。因此,您可以在列表中存储
对象
(或
WeakReferences
对象
),或者使用不同的方法(例如,通过反射获取所有类)。但是,在某种程度上,检索所有管理器的方法的返回类型必须是
object

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

然而,在这种情况下,使用泛型有一些缺点。类
SpecialContextManager
可以强制转换为
ContextManager
。那很好。但是,此类不能转换为
ContextManager
,因为它们是两个不同的类。因此,你不能打电话
RegisterInstance(ContextManager)
传递一个具体的管理器。因此,您可以在列表中存储
对象
(或
WeakReferences
对象
),或者使用不同的方法(例如,通过反射获取所有类)。但是,在某种程度上,检索所有管理器的方法的返回类型必须是
object

public abstract class ContextBase
{
}

public abstract class ContextManager<T> where T: ContextBase
{
    // contains all the context managing logic.
    public T FindContext()
    {
       // ...
    }
}
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
}
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
}
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);
     }
}