Tuesday, September 16, 2014

Overriding without virtual and override keywords in .Net

This is about a particular scenario where we can achieve overriding without virtual or override keywords in C#. Below is the scenario of an inheritance hierarchy.
Here we can see that both the base and derived class implemented the IDisposable interface. In this case we don't need to mention the keyword overrides but the Dispose() of DerivedDisposable class will be called when we invoke the Dispose() method on the IDisposable type variable, if it contains the DerivedDisposable class object.

            IDisposable id = new DerivedDisposable();
            id.Dispose();

This will invoke the method written inside the DerivedDisposable class.

Calling base class Dispose method

Normally in overriding scenarios, we may call the base class implementation by using base.OverriddenMethodName(). But in this case, base object will not have the Dispose method, if the IDisposable is implemented explicitly. Means the code below won't compile.


    class DerivedDisposable : Disposable,IDisposable
    {
        void IDisposable.Dispose()
        {
            base.Dispose();//This wont compile if the base class / class Derived in this example implements the IDisposable explicitly
        }
    }


Next idea what we can do is to cast the base to IDisposable and call the Dispose method. But that too won't compile.


    class DerivedDisposable : Disposable,IDisposable
    {
        void IDisposable.Dispose()
        {
            //DoWork();
            (base as IDisposable).Dispose();//Won't compile
        }
    }

Implicit interface implementation

Only way to call the base class Dispose method is to make sure the base implements the interface implicitly.Then we can call base.Dispose method().


    class Disposable : IDisposable
    {
        public void Dispose()
        {
            Console.WriteLine("Disposable.Dispose");
        }
    }
    class DerivedDisposable : Disposable,IDisposable
    {
        void IDisposable.Dispose()
        {
            //DoWork();
            base.Dispose();
        }
    }


If we are concerned about having additional public function, another workaround is to have separate protected function in base class (eg:DisposeWorker) which is called from the Dispose() of base class to carry out the task. So from the derived class.Dispose() method we can call that protected function.


    class Disposable : IDisposable
    {
        void IDisposable.Dispose()
        {
            DisposeWorker();
        }
        protected void DisposeWorker()
        {
            Console.WriteLine("Disposable.Dispose");
        }
    }
    class DerivedDisposable : Disposable,IDisposable
    {
        void IDisposable.Dispose()
        {
            //DoWork();
            base.DisposeWorker();
        }
    }

Real scenario - Overriding the ClientBase<TChannel>.Dispose

This is useful when overriding the Dispose method of ClientBase<TChannel> class related to WCF to have our own behavior when disposing. In our project as I mentioned in earlier posts, we are not adding service reference to call WCF service. Instead we create our own proxy class by implementing ClientBase<TChannel>. We have proxy pooling technique built into the system and it needs "return  of proxy to the pool" when Dispose is called on proxy object.


    class Client : ClientBase<IService1>, IService1IDisposable
    {
        void IDisposable.Dispose()
        {
            Console.WriteLine("Disposable.Dispose");
        }
 
        string IService1.GetData(int value)
        {
            throw new NotImplementedException();
        }
    }


I am really not sure whether its overriding or 'feels like' overriding. Anyway I am open to discussions. This is one of the scenario I could see which can only be solved by using implicit interface implementation.We will face this same issue if we implement interfaces explicitly in VB.Net.

Happy coding

No comments: