2

I am using FileHelpers in one project, and the class MultiRecordEngine

public sealed class MultiRecordEngine
    : EventEngineBase<object>, IEnumerable, IDisposable

This class implements IDisposable, BUT don't have a public Dispose method...

MultiRecordEngine eng = null;
eng.Dispose(); // <---- Results in compilation error

Inspecting this class code on GitHub I can see the method implemented explicitly here, line 913:

void IDisposable.Dispose()
{
    Close();
    GC.SuppressFinalize(this);
}

So... Why cannot I invoke the method? Is this intended, and if so, is it a good practice, and in what circumstances?

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
RMalke
  • 4,048
  • 29
  • 42
  • Seems like a pain in the rear, and counter-intuitive. I'd like to hear if anyone can offer some benefit to explicitly implementing IDisposable. – hatchet - done with SOverflow Aug 20 '13 at 15:07
  • similar questions: http://stackoverflow.com/questions/3119288/why-would-a-class-implement-idisposable-explicitly-instead-of-implicitly and http://stackoverflow.com/questions/5577252/explicit-implementation-of-idisposable and http://stackoverflow.com/questions/408415/why-explicit-interface-implementation – hatchet - done with SOverflow Aug 20 '13 at 15:09
  • @hatchet A possible reason is that it is nice to have the Intellisense list uncluttered by Dispose() that will 99% of the time not be invoked directly. – Keith Payne Aug 20 '13 at 15:21
  • @KeithPayne - except that having Dispose() appear in the Intellisense list may be the tip off needed to make the programmer aware that it's something that needs disposing. If it doesn't appear, they may just assume it doesn't implement IDisposable. – hatchet - done with SOverflow Aug 20 '13 at 15:42
  • 1
    @hatchet: The primary case where explicit implementation makes sense is when a class implements an interface that implements `IDisposable` (e.g. `IEnumerator`) but the `Dispose` method does nothing. Microsoft suggests that things with methods called e.g. `Close`, `Shutdown`, etc. may implement `Dispose` explicitly to suggest that it's redundant with those other methods, but I really dislike that pattern since there's nothing to indicate what methods are adequate substitutes for `Dispose` (some classes may keep resources after `Close` to allow for being re-opened). – supercat Aug 20 '13 at 18:42

2 Answers2

5

It's implemented explicitly, so you need to cast to IDisposable:

((IDisposable)eng).Dispose();

explicitly implemented members are only accessible through the interface, not the implementing class.

Lee
  • 142,018
  • 20
  • 234
  • 287
  • 1
    Ashamed of myself. I always thought the explicitly implementation had no effect in the client code. Thanks – RMalke Aug 20 '13 at 15:03
1

First, you can invoke the method by casting to IDisposable:

((IDisposable)eng).Dispose();

You can also properly use the class in a using block:

using (MultiRecordEngine eng = new MultiRecordEngine())
{
..
}
Keith Payne
  • 3,002
  • 16
  • 30