Rewritten: Since we're talking about implementing IDisposable what really matters is ensuring that both the Derived and Base classes have the opportunity to run their respective cleanup code. This example will cover 2/3 of the scenario's; however since it derives from Base() and Base.Dispose() is not virtual, calls made to ((Base)Child).Dispose() will not provide the Child class with the chance to cleanup.
The only workaround to that is to not derive Child from Base; however that's been ruled out. Calls to ((IDisposable)Child).Dispose() and Child.Dispose() will allow both Child and Base to execute their cleanup code.
class Base : IDisposable
{
public void Dispose()
{
// Base Dispose() logic
}
}
class Child : Base, IDisposable
{
// public here ensures that Child.Dispose() doesn't resolve to the public Base.Dispose()
public new void Dispose()
{
try
{
// Child Dispose() logic
}
finally
{
// ensure that the Base.Dispose() is called
base.Dispose();
}
}
void IDisposable.Dispose()
{
// Redirect IDisposable.Dispose() to Child.Dispose()
Dispose();
}
}