14

Although there are quite a lot of Q&As regarding IDisposable to be found on SO, I haven't found an answer to this yet:

I usually follow the practice that when one of my classes owns an IDisposable object then it also implements IDisposable and calls Dispose on the owned object. However recently I came across a class which implemented IDisposable explicitly thus preventing me from directly calling Dispose forcing me to cast it which I found annoying and unnecessary.

So the question: Why and when would one want to use an explicit interface implementation of IDisposable? I know that there are perfectly good and valid reason for implementing an interface explicitly but in regards to IDisposable the reason is not quite clear to me.

Tomek Szpakowicz
  • 14,063
  • 3
  • 33
  • 55
ChrisWue
  • 18,612
  • 4
  • 58
  • 83
  • 1
    What are these "good and valid reasons", and why shouldn't they hold for `IDisposable` as well? And why is it "annoying" to cast an object to `IDisposable`? – chiccodoro Apr 07 '11 at 07:09
  • 2
    Sometimes it is necessary for a class to implement two or more interfaces whose member names would conflict. That's a fine and proper use for explicit interface naming. I agree with the OP that the convention of arbitrarily naming the cleanup method something other than Dispose is silly. Even if a class has a Close method, that doesn't mean it shouldn't also have a Dispose method. Since calling Dispose after calling Close is at worst mildly redundant, what's wrong with having both methods? – supercat Apr 07 '11 at 07:21
  • @chiccodoro: IMO explicit interface implementation is useful mostly when one needs to implement two interfaces which have conflicting members. In any other case having an object which can be cast to an interface instead of "being" the interface is unnatural and annoying. – Tomek Szpakowicz Apr 07 '11 at 07:22
  • @chiccodoro: I think this SO question covers it quite well: http://stackoverflow.com/questions/143405/c-interfaces-implicit-and-explicit-implementation – ChrisWue Apr 07 '11 at 07:38
  • @supercat: Didn't really get your point about Close etc. I said "why shouldn't these reasons hold for IDisposable as well?" - means: If the object implements an interface which happens to have a "Dispose" method, but is different from IDisposable, then an explicit implementation is required, isn't it? – chiccodoro Apr 07 '11 at 08:53
  • @chiccodoro: Not if the object exposes both a Close method and a Dispose method (one of which could call the other, or both of which could call a common internal routine). – supercat Apr 07 '11 at 15:13

3 Answers3

16

I'd say it's unusual to have an explicit implementation of IDisposable.Dispose unless you have an alternate equivalent method (e.g. Close).

In which case your wrapper class could call Close rather than casting.

An example is the WebResponse class in the Framework <= V3.5. Interestingly there is a public Dispose method in .NET 4, so maybe Microsoft has now decided that an explicit implementation may not be good practice.

Shawn Farkas, a design engineer on the CLR security team writes in MSDN magazine that

Although the using block will work with classes that do have an explicit IDisposable implementation, I recommend that classes never implement the interface this way. If you explicitly implement IDisposable, developers who are exploring your object model using IntelliSense® in Visual Studio® will not notice that the object has a Dispose method

Joe
  • 122,218
  • 32
  • 205
  • 338
  • Indeed the class I wanted to wrap exposed a `Close` method which I ended up using. It's just that the sample code provided explicitly contained: `using (SomeClass o = new SomeClass())` so it was clear that the use of the disposable pattern was encouraged. – ChrisWue Apr 07 '11 at 07:44
1

I would say it's good practice, it forces (unless you want to cast to IDisposable!!) the use of using

using (ClassWithIDisposable) {
}

Dispose will be called even in the event of an exception

Also when using IOC frameworks like castle and unity you end up having to inherit IDisposable to your interface so it can be called. These frameworks allow for AOP whereby you don't have a reference to your solid class only an interface......

James Kyburz
  • 13,775
  • 1
  • 32
  • 33
  • A using statement is not appropriate for the scenario described in the question - a class that owns an IDisposable object. – Joe Apr 07 '11 at 07:34
  • It doesn't really enforce the use of `using`. Nobody can stop you from doing something like this `var o = new MyDisposable(); o.DoSomething(); return;` – ChrisWue Apr 07 '11 at 07:34
  • True! Neither does having it public... I just mean instead of calling .Dispose() explicitly – James Kyburz Apr 07 '11 at 07:43
  • Sure, but as Joe said, in my case I instantiated the object in the constructor and wanted to dispose it in the `Dispose` method - so using is not an option. – ChrisWue Apr 07 '11 at 07:46
  • 2
    Hiding the `Dispose` method behind an explicit interface implementation means that the developer might not even realise that the class implements `IDisposable`. Not a good idea: if your class needs to be disposed then you should advertise that information as obviously as you can. – LukeH Apr 07 '11 at 09:17
1

IMHO, there's only one proper reason for a class to implement IDisposable explicitly, which would be if it's expected that nobody would actually have to call it. The fact that a class implements IDisposable explicitly could be seen as an indicator that one may safely create an object of that particular class, though not necessarily an object of a derived class, and simply abandon it when one was done with it. The lack of a directly-available Dispose method on a particular class could then be seen as an indicator that calling Dispose on an object known to be of that particular class would not be needed.

Note that having and using a reference to an object which implements IDisposable, without realizing that it does, is not a problem; acquiring ownership of such an object, however, is. A factory method whose return type does nothing with IDisposable.Dispose and implements it explicitly, but which sometimes returns an object that expects proper Disposal, would be a recipe for leaks. A class should not explicitly implement IDisposable if it might be used as the return type of such a factory method.

Personally, my inclination would be to Dispose all objects that implement IDisposable, whether they need it or not. Nonetheless, knowing that certain particular types of IDisposable object may be very useful in cases where ensuring proper disposal would otherwise be difficult or awkward.

supercat
  • 77,689
  • 9
  • 166
  • 211