Disposing an IDisposable object stored in a public static field

邮差的信 提交于 2019-12-23 17:24:34

问题


If a class has an instance field that implements IDisposable then the containing class implements IDisposable and class that fields Dispose method from within its Dispose method.

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

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

(I know I didn't do the dispose pattern correctly, but for sample code should be good enough)

If the field is a static field though where should the call to the field's Dispose be?

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

I could make class B implement IDisposable and have that call font.Dispose but if B.font is used again later on that would cause problems. As well as you'd have to remember that dispise accessing a static method you need to create an instance just to call Dispose.

I could also make a static Dispose method but then users have to remember to call Dispose and have to make sure they're the last user of it in the program.


回答1:


Static fields are initialised when the type is loaded.

Therefore it logically it makes sense to dispose the object assigned to the static field when the containing type is unloaded.

However, types are not unloaded. There may be some exotic complication here around AppDomains, but I suspect that doesn't apply in your case.

Therefore I wouldn't dispose the instance, otherwise you will have a publicly available instance of an object that is unfit for use.




回答2:


If the field is static, then maybe the intention is to have it last for the complete duration of the application? Because then it will only need to be disposed of when the application shuts down. And that will happen one way or the other, by itself-

If you plan to reassign the static field to different IDisposable objects several times during the lifetime of the application, then of course you would want to dispose the old object when you reassign. Maybe you could use a property for that? Not that I have thought a lot about it, but something like:

// 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;
  }
}



回答3:


You dispose of it like any other object. It doesn't make a difference. A static object is just an object that is available per class. It's still an instance of something. Granted, you probably wouldn't want to do this since after you dispose of it someone can still access it and get a ObjectDisposedException exception.

    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");
        }
    }

And the output is:

Disposed

Per your updated example:

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

You can just do A.font.Dispose() or using(A.font)

In general I think the idea is you really wouldn't have a public static disposable field since by making it static you imply it should be around for the lifetime of the application. If it has to be disposable you should could make it lazy and make it be thread-safely re-initializable, otherwise accessing it after disposing will throw exceptions. Or you can have a hook into your application end code and safely dispose of all static disposables there. You can register your disposable on start somewhere as well. Just an idea




回答4:


You can't dispose a static class because there is no instance of it



来源:https://stackoverflow.com/questions/14032941/disposing-an-idisposable-object-stored-in-a-public-static-field

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!