6

如果一个类有一个实现 IDisposable 的实例字段,那么包含的类实现 IDisposable 和从其 Dispose 方法中字段 Dispose 方法的类。

public class A : IDisposable 
{
    public System.Drawing.Font font = new Font("Arial", 10.0f);

    public void Dispose()
    {
        font.Dispose()
    }
}

(我知道我没有正确执行 dispose 模式,但是对于示例代码应该足够好了)

如果该字段是静态字段,那么对该字段的 Dispose 的调用应该在哪里?

public class B
{
    public static System.Drawing.Font font = new Font("Arial", 10.0f);
}

我可以让 B 类实现 IDisposable 并进行调用,font.Dispose但是如果稍后再次使用 B.font 会导致问题。您还必须记住,访问静态方法的 dispise 您需要创建一个实例才能调用 Dispose。

我也可以创建一个静态 Dispose 方法,但是用户必须记住调用 Dispose 并且必须确保他们是程序中的最后一个用户。

4

4 回答 4

11

加载类型时初始化静态字段。

因此,在卸载包含类型时处理分配给静态字段的对象从逻辑上讲是有意义的。

但是,类型不会被卸载。AppDomains 周围可能存在一些奇异的复杂情况,但我怀疑这不适用于您的情况。

因此我不会处置该实例,否则您将拥有一个不适合使用的对象的公开可用实例。

于 2012-12-25T18:51:32.633 回答
3

如果该字段是静态的,那么可能的目的是让它在整个应用程序期间持续存在?因为只有在应用程序关闭时才需要处理它。这会以一种或另一种方式发生,它本身——

如果您计划IDisposable在应用程序的生命周期内多次将静态字段重新分配给不同的对象,那么您当然希望在重新分配时处理旧对象。也许您可以为此使用属性?并不是我想了很多,而是类似:

// private - don't write to this field from outside the property setter
static Font font = new Font("Arial", 10.0f));

public static Font Font
{
  get
  {
    return font;
  }
  set
  {
    var oldFont = font;
    if (oldFont != null)
      oldFont.Dispose();
    font = value;
  }
}
于 2012-12-25T18:51:34.663 回答
2

您可以像处理任何其他对象一样处理它。这没什么区别。静态对象只是每个类可用的对象。它仍然是某事的一个实例。当然,您可能不想这样做,因为在您处理它之后,仍然有人可以访问它并获得ObjectDisposedException异常。

    static void Main(string[] args)
    {
        using (Test.Instance)
        {

        }  

        Thread.Sleep(TimeSpan.FromSeconds(10));
    }

    public class Test:IDisposable
    {
        public static Test Instance = new Test();
        public void Dispose()
        {
            Console.WriteLine("Disposed");
        }
    }

输出是:

处置

根据您更新的示例:

public class A
{
    public static System.Drawing.Font font = new Font("Arial", 10.0f));
}

你可以做A.font.Dispose()using(A.font)

一般来说,我认为这个想法是你真的不会有一个公共的静态一次性字段,因为通过使其成为静态你暗示它应该在应用程序的生命周期内存在。如果它必须是一次性的,你应该让它变得懒惰并使它可以线程安全地重新初始化,否则在处理后访问它会抛出异常。或者,您可以挂钩到您的应用程序端代码,并在那里安全地处理所有静态一次性用品。您也可以在某个地方开始注册您的一次性用品。只是一个想法

于 2012-12-25T18:17:15.353 回答
-2

您不能处置静态类,因为没有它的实例

于 2012-12-25T18:28:15.290 回答