Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In an IDisposable pattern should a base class allow derived classes to share its disposed flag?

I am currently working on fixing a c# codebase which does not have a good pattern of Dispose usage.

It is a large codebase, it is a resource demanding codebase and it uses many custom unmanaged c++ libraries at the low level.

I have a good understanding of the dispose pattern. I have spent some time understanding what I believe to be the gold standard article on the issue: Joe Duffy's dispose article

In an attempt to minimise code duplication, we have been considering some dispose helper classes, and so my question:

If a base class implements a standard Dispose pattern should it allow its disposed flag to be shared ie. marked as protected?

To clarify I mean should there only be a single boolean state within an inheritance heirarchy that defines whether an object instance has been disposed or should there be a private boolean at each step of the inheritance ladder?

The examples in MSDN and at the above link set a flag at each level, but never explain the reasoning behind it. I am in two minds on the issue, what are your thoughts and reasons?

like image 963
morechilli Avatar asked Jul 03 '09 15:07

morechilli


People also ask

How can we use IDisposable class?

For implementing the IDisposable design pattern, the class which deals with unmanaged objects directly or indirectly should implement the IDisposable interface. And implement the method Dispose declared inside of the IDisposable interface. We do not directly deal with unmanaged objects.

What happens if Dispose is not called?

Implement a finalizer to free resources when Dispose is not called. By default, the garbage collector automatically calls an object's finalizer before reclaiming its memory. However, if the Dispose method has been called, it is typically unnecessary for the garbage collector to call the disposed object's finalizer.


1 Answers

I would say no it should not share the flag. Sharing the flag creates opportunities for failure which better encapsulation could prevent.

For instance, consider the scenario where you have a readonly Disposed property on the base most class. The backing field is only set to true in the Dispose(disposing) method on the base class. This means that the property Disposed can only ever return true if the base class Dispose is called (barring evil reflection of course). This allows the base class to provide an enforceable contract.

Now consider the opposite, where there is a protected setter. Any class can now arbitrarily set the Disposed property to true without disposing anything. This creates an opportunity for Dispose to return true when nothing is disposed.

I would choose the first option because it provides the most enforceable contract.

like image 122
JaredPar Avatar answered Oct 22 '22 14:10

JaredPar