【问题标题】:Base class to hold collection instances of derived classes保存派生类的集合实例的基类
【发布时间】:2013-01-04 01:29:22
【问题描述】:

我的 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 的构造函数不正确。我是不是漏了个小把戏?

【问题讨论】:

  • 不要这样做;这是内存泄漏。你的终结器永远不会运行。 (你不应该首先使用终结器)
  • @SLaks 这可以通过IDisposable 实现而不是终结器来实现吗?
  • @KonstantinVasilcov:这仍然是个坏主意。
  • 这不是资源管理的问题;我故意遗漏了与此有关的细节。告诉我不要做某事没有帮助(特别是告诉我不应该使用终结器)。

标签: c# oop generics inheritance


【解决方案1】:

这是我使用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))
{

}

这里对于派生自Base&lt;T&gt; 的任何类都没有public 构造函数。而静态工厂GetInstance 方法应该用于创建实例。请记住,只有在调用 Dispose 方法时才会从字典中删除实例,因此您应该使用 using statement 或手动调用 Dispose

不过,我想您仍然应该考虑 SLaks 的评论。

【讨论】:

    猜你喜欢
    • 2013-02-12
    • 2023-03-19
    • 2014-04-27
    • 2014-09-29
    • 1970-01-01
    • 2019-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多