0

This has to have been asked lots of times, yet I cannot find a single place in the internet mentioning the problem.

The situation is too simple to believe it has no solution:

public class BaseDispose : IDisposable
{
    void IDisposable.Dispose()
    {

    }
}

public class ChildDispose : BaseDispose, IDisposable
{
    void IDisposable.Dispose()
    {
        //var disp = base as IDisposable;
        //(base as IDisposable).Dispose();
    }
}

There is a base class that has unmanaged resources. For some reason it disposes of them via an implicit realization of IDisposable. There is a class that derives from this base class that has to get rid of both his own and his parent's resources.

How can this be done in c#? Both lines I commented out above result in a compilation error

  • Like the sales rep that stops a farmer down a boreen in rural Ireland and asks "Could you tell me how to get back to Dublin?" and the ould fella says "Dublin? Well, I'll tell you one thing, I wouldn't start from here". Can you change the source for BaseDispose and ChildDispose? Because this implementation of Dispose is insane, and deviates far from the [recommended pattern](http://msdn.microsoft.com/en-us/library/ms182330.aspx) – Binary Worrier Oct 22 '13 at 10:44
  • 1
    @Binary I wish guys from Microsoft knew they deviated from the pattern recommended by Microsoft! Because this is exactly the way they implemented System.ServiceModel.ClientBase. – Leonid Zakirov Oct 22 '13 at 11:41
  • Sweet f**k me Jebus! Are you serious? Off to have a poke . . . – Binary Worrier Oct 22 '13 at 11:44

1 Answers1

1

If you have access to both of those classes then change them to properly implement the Disposable pattern

If you don't have access to the base class, then another thing to try is to change the Child class to not inherit the base class, but to contain an instance of it as a member, and delegate to it where you would normally call base.
However this won't work if you've to pass the child class to something expecting base, you won't be able to treat them polymorphically.

Otherwise I can't see a way out of your particular pickle.

Update
OK, having reflected the code and inspected System.ServiceModel.ClientBase<TChannel>.Dispose() I can tell you it simply calls it's Close() method, so having your dispose method call base.Close() will be functionally equivalent, but is obviously less than ideal.

Also, you'll either seal your class or implement IDispose correctly (i.e. by not implicitly implementing IDisposable) won't you?

Futher update

It should be OK to call Close() instead of dispose as stated here Close & Dispose, which to call?

And here's an example of a ClientBase<T> implementation including it's dispose method, which conditionally calls Close() or Abort()

Hope this helps

Community
  • 1
  • 1
Binary Worrier
  • 50,774
  • 20
  • 136
  • 184
  • Unfortunately, I can't change the base class as it is provided to me by WCF. The class is System.ServiceModel.ClientBase, it is marked as abstract and public and so it is supposed to be derived from, I believe. And oh, it implements IDisposable implicitly. – Leonid Zakirov Oct 22 '13 at 11:44
  • 1
    Thank you so much for your time and research! This surely solves my actual problem but leaves the one stated as topic starter unresolved, unfortunately. Let's take it for an example of bad design the WCF team overlooked somehow. I'm marking your response as an answer. – Leonid Zakirov Oct 22 '13 at 12:16