Using Keyword & IDisposable in C#


The using keyword can be used as a:
·         Directive, when it is used to create an alias for a namespace or to import types defined in other namespaces.
·         Statement, when it defines a scope at the end of which an object will be disposed.


"using" as statement Provides a convenient syntax that ensures the correct use of IDisposable objects, which provides a mechanism for releasing unmanaged resources. IDisposable interface implements Dispose method to explicitly release unmanaged resources in conjunction with the garbage collector. The consumer of an object can call this method when the object is no longer needed.

The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object.


NOTE: - The garbage collector automatically releases the memory allocated to a managed object when that object is no longer used. However, it is not possible to predict when garbage collection will occur. Furthermore, the garbage collector has no knowledge of unmanaged resources such as window handles, or open files and streams.


IDisposable Interface
Using block can only be used for the classes that implement the IDisposable interface. In other cases you need to implement IDisposable then you can call the IDisposable.Dispose implementation from the finally block of a try/catch statement.

Following code shows implementation of IDisposable interface.

using System;
using System.ComponentModel;

public class DisposeExample
{
    // Create a base class that implements IDisposable.
    public class DerivedClass : IDisposable
    {
        // Pointer to an external unmanaged resource.
        private IntPtr handle;
        // Other managed resource this class uses.
        private Component component = new Component();
        // Track whether Dispose has been called.
        private bool disposed = false;

        // The class constructor.
        public DerivedClass(IntPtr handle)
        {
            this.handle = handle;
        }

        // Implement IDisposable.
        // Do not make this method virtual, Derived class should not be able to override this method.
        public void Dispose()
        {
            Dispose(true);
            // This object will be cleaned up by the Dispose method.
            // Therefore, you should call GC.
            // SupressFinalize to take this object off the finalization queue and prevent finalization code for this object from executing a second time.
            GC.SuppressFinalize(this);
        }

        // Dispose(bool disposing) executes in two distinct scenarios.
        protected virtual void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if (!this.disposed)
            {
                // If disposing equals true, dispose all managed
                // and unmanaged resources.
                if (disposing)
                {
                    // Dispose managed resources.
                    component.Dispose();
                }

                // Call the appropriate methods to clean up unmanaged resources here.               
                CloseHandle(handle);
                handle = IntPtr.Zero;

                // Note disposing has been done.
                disposed = true;

            }
        }

        // Use interop to call the method necessary to clean up the unmanaged resource.
        [System.Runtime.InteropServices.DllImport("Kernel32")]
        private extern static Boolean CloseHandle(IntPtr handle);

        // Use C# destructor syntax for finalization code.
        // This destructor will run only if the Dispose method does not get called.
        // It gives your base class the opportunity to finalize.
        // Do not provide destructors in types derived from this class.
        ~DerivedClass()
        {
            // Do not re-create Dispose clean-up code here.
            // Calling Dispose(false) is optimal in terms of
            // readability and maintainability.
            Dispose(false);
        }
    }
    public static void Main()
    {
        // Insert code here to create
        // and use the DerivedClass object.
    }
}

Comments