Dispose required if using interface
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.
精彩评论