9
votes

In C#, as mentioned in the Documentation, and this nice post's accepted answer, it's stated that classes don't inherit the Destructor of their parent class.

The question : If I want to make sure to dispose the private elements of the base class, is the proper way to implement IDisposable in all the child class, and in the Dispose method, call base.Dispose()?

It looks alright to do so, but I would have preferred a way which wouldn't require implementation in all of the child classes.

4
Please only do this if your "private elements" are unmanaged resources.Henk Holterman
@Henk: Whether or not the "private elements" of the base class are unmanaged is an implementation detail that the child classes shouldn't really care about. If your base class implements IDisposable then it should be disposed.LukeH
In this case, the private elements of the base class are indeed unmanaged resources, but as LukeH said, the child classes are not 'aware' of this.Tipx
@lukeh: implementing IDisposable and having to be Disposed are separate from having (needing) a destructor.Henk Holterman
@LukeH: If a class or its parent class implements a finalizer, then it and all derived classes will likely have to use GC.KeepAlive in many cases that would not otherwise be necessary (or else risk random failures). This is not a private "implementation detail". If .net provided a means of tagging a class in such a way as to require the jitter to always regard "self" as live, the issue of finalization might be abstracted away, but I'm unaware of any such means.supercat

4 Answers

16
votes

MSDN states that destructors are called on base classes automatically.

7
votes

You should follow the Disposable pattern here. It also caters for inheritance.

The interesting part here is "destructors don't inherit", I'm not sure what to make of that. I wrote a little test but to my relief you only need to write a destructor in the base-class.

So the children are uncoupled from the base-class unmanaged resources. They can override Dispose(bool) to cleanup their own affairs.

But I made a comment because I see too many programmers implementing the full pattern just to handle managed resources.

From a general design perspective, a Disposable class would better be sealed.

0
votes

The base class should use the standard IDisposable pattern for base classes - in this way only the base class needs a finalizer, and derived classes simply override the virtual method

protected void Dispose(bool disposing)
0
votes

If the parent class uses Microsoft's IDisposable pattern, the child class should not override Dispose(void) but instead override Dispose(Boolean Disposing). If called with Disposing true, it should dispose the child class and call base.Dispose(True). If called with Disposing false, it should in most cases no nothing except call base.Dispose(False).

Note that in most cases, the call to base.Dispose(False) will do nothing, but it should be made anyway. If the child class would need to add additional "unmanaged resources" (i.e. if it has additional responsibilities that need to be performed in a finalizer) it should generally encapsulate those responsibilities into another object. Note that the question of whether a class has a finalizer is not just an "implementation detail"; adding a finalizer to a base class can be a breaking change, causing a program which would have leaked resources (bad, but perhaps survivable if it the program isn't run for too long at a time) into one which will, on random occasions, attempt to clean up resources which are still in use (won't often cause problems, but may cause rare but immediate failures).