开发者

Dispose required if using interface

开发者 https://www.devze.com 2023-01-16 06:04 出处:网络
Let\'s say I\'ve got a My开发者_运维问答Object object that has two interfaces: IMyContract and IDisposable. And I have this code in a method:

Let's say I've got a My开发者_运维问答Object object that has two interfaces: IMyContract and IDisposable. And I have this code in a method:

IMyContract blah = new MyObject();
blah.Blah();
return;

This is a potential memory leak, right? Doesn't it need to be:

using (MyObject blah = new MyObject())
{
    blah.Blah();
}
return;


Well, if it implements IDisposable you should indeed dispose it. There's no saying what will leak if you don't - or for how long - but you should have a using statement to avoid it anyway.

(Just to clarify: memory is the least likely thing to be leaked, as IDisposable is generally about unmanaged resources such as network connections etc. It's possible, of course - the object could have a handle on some memory allocated far away from the GC's gaze. Any implementation of IDisposable which holds direct references to unmanaged resources should also have a finalizer, so the leak should only be temporary... but that could still be painful.)


you could call dispose in your first example as well:

IMyContract blah = new MyObject();
blah.Blah();
((IDisposable)blah).Dispose();
return;

not quite as clean, but sometimes you must use interfaces.

The other possibility is for your Interface to itself inherit IDisposable. Then you could use:

using (IMyContract blah = new MyObject())
{
    blah.Blah();
}
return;


If IDisposable is implemented properly (with a finalizer that calls Dispose() and no SuppressFinalize), the Garbage Collector will get to it eventually. However, using() is the same as try { ... } finally { object.Dispose(); }, which will deterministically (explicitly, as soon as possible) dispose. If you depend on the Garbage Collector you may be surprised how long it takes to dispose. If there are unmanaged resources, you could quickly run out of them because they haven't been deallocated.

Edit: I missed the point of this the first time around. Yes, when you use MyObject you should Dispose() properly with using(). If you have other code that uses that interface then you could have something like:

public IMyContract GetInterface()
{
  using (MyObject obj = new MyObject())
  {
    obj.DoSomething();
    return (IMyContract)obj;
  }
}

The rest of the code can then use IMyContract contract = GetInterface(); without having to worry about (or even knowing) that things should dispose.


Technically, you cannot cause a memory leak. However, you may end up holding resources open longer than necessary.

If implementors of IMyContract normally are disposable (or likely could be disposable), then IMyContract should inherit from IDisposable. Otherwise, you could just have MyObject inherit from IDisposable.

Either way, the object should certainly be disposed.

0

精彩评论

暂无评论...
验证码 换一张
取 消