Thursday, December 13, 2012

Disposable interface - how do I know

Many developers that I met had a problem to figure out if a class that they used implemented IDisposable interface. Consider a following code:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class ContentHubDataCacheSoapClient : System.ServiceModel.ClientBase, ContentHubDataCacheSoap {
}
When I create an instance of ContentHubDataCacheSoapClient should I dispose it?

What Developers typically did is used Object Browser to see if there is a method called Dispose, see a picture below for an example matching a code above :)
It's easy to see that there is no Dispose method listed there, but I circled in the red where one can see if a class implements IDisposable interface.

Other developers to answer a question suggested that IDisposable can be satisfy by implementing a Close method (this is not true, see code example below).

But why Dispose method was not listed in a list of methods. The answer is as simple as to understand that one can implement a method explicitly naming an interface that requires it, and thanks to that it will not be listed in Object Browser. An example is below.
public class DisposingClass : IDisposable
    {
        public void Dispose() { }
    }

    public class ClosingClass{
        public void Close() { }
    }

    public class ImplementingDisposableInterfaceClass : IDisposable {
        void IDisposable.Dispose() {
            Close();
        }

        public void Close() { }
    }

    public class ChildClass : ImplementingDisposableInterfaceClass { }

    public class UsingClass {
        public void UsingMethod() {
            // Compilation time exception, IDisposable needs to implement IDisposable.
            using (var c = new ClosingClass()) { 
            }

            // Typical way of implementing Disposable.
            using (var d = new DisposingClass())
            {
            }

            using (var d = new ImplementingDisposableInterfaceClass())
            {
            }

            // Dispose method will not be showed in Object Browser
            using (var d = new ChildClass())
            {
            }
        }
    }

No comments: