Why would a class implement IDisposable explicitly instead of implicitly?
-
30-09-2019 - |
Question
I was using the FtpWebResponse class and didn't see a Dispose method. It turns out that the class implements IDisposable, but does so explicitly so that you must first cast your instance to IDisposable before calling Dispose:
// response is an instance of FtpWebResposne
((IDisposable) response).Dispose();
Why would the designer of a class such as this one choose to implement IDisposable explicitly? As Anthony Pegram says, doing things this way masks the fact that the object should be disposed for the average developer who is not consulting the documentation every time he/she uses a class.
Solution
This is normally done if the class has a Close
method that is the exact same as Dispose
. The original Dispose
is hidden in an explicit implementation so that the exact same method doesn't have two names.
It's officially recommended here:
(P.S. I disagree with this convention.)
OTHER TIPS
- Occasionally a class will have a Dispose method that is part of the interface but doesn't actually need to be called because the only resource to dispose of is memory: MemoryStream, for example.
- As mentioned by others, if the class has a Close method that does the same thing as Dispose, arguably Dispose only needs to exist to support the "using" pattern so it may as well be explicit.
It's a little weird looking to me too. For what it's worth: the base class (WebResponse) implements a Close() method. Reflector shows that WebResponse's Dispose() method just calls Close() and an Internal OnDispose virtual that does nothing.
I have to confess that it smells a little to me, but I bet that they explicitly implemented IDisposable so that there would not be confusion in Intellisense between calling Close() or Dispose().
In addition to what's been said, I might suggest that implementing IDisposable
explicitly encourages use of the using
block, as it can be used on any type which implements IDisposable
and it is more natural (to most people, anyway) to write this:
using (var response = GetResponse())
{
// do something
}
Than this:
var response = GetResponse();
// do something
((IDisposable)response).Dispose();
I'm not sure that would be a developer's intention in explicitly implementing IDisposable
, but it's possible.