Saturday, September 24, 2011

Internals of Interface and its Implementation

As many of my followers requested me to write few things that I missed out from the Internals Series, I should continue with it. In this post, I will cover the internals of Interface implementation and mostly talk about explicit interface implementation, as most of the developers seems to be in confusion with it. I hope you will like the post.

Beginning from the basics, Interfaces are the most important part of any application. Interfaces are language construct that does not implement anything but declares a few members upfront. Generally we use interfaces to create a contract between the two or more communication agents. Another important thing that everyone would be knowing already, Interfaces are meant to be implemented. That means whenever you are creating a class, all the members that were there in the interface are meant to be implemented completely. .NET (or probable any other standard language) disallows the creation of objects on types that are not fully defined. Hence abstract classes also coming into play here. They are classes that have few members undefined or abstract. Once you don't have concrete implementation, you cannot create an instance of a type. Notably, you can say "Interface is a types that does not belong to the System.Object or implement it when it reside inside an assembly". But ironically you could also says that once the type is implemented, it would probably inherit from System.object by default.




Another important OOPS feature is that you can hold reference of any concrete type to any of its base implementations. By this what I mean, if say class X derived from Y and implements Z (where Z is an interface) you can say either Y y1 = new X() or Z z1 = new X().

Now lets define an interface and start some tweaks some of its behaviors.

public interface IA
{
    void GetX();
}

Let us suppose we have an interface IA which has a method GetX(). Now you should remember, it is not allowed to use access specifier for members of an interface as that mean the implementers of this interface needs to specify access specifiers for its members and it would appear to all implemtors that these members are public.  Now lets see one implementation of it.

public class A : IA
{
    public void GetX()
    {
        Console.WriteLine("Here is X: Normal");
    }
    void IA.GetX()
    {
        Console.WriteLine("Here is X: Explicitely");
    }
}

A is a class which implements IA, and hence need to declare one member GetX. Now you can see here we have defined two implementation of the same method GetX. The other one is Explicit implementation of IA.  The explicit declaration of a method can only be done for Interfaces (not allowed for normal classes) and allows you to differentiate the calls to GetX to its explicit implementation when interface is used rather than a normal derived reference is used.  Hence if I call :

A a1 = new A();
a1.GetX(); // prints Here is X: Normal

IA a2 = a1;
a2.GetX(); //Prints Here is X: Explicitely

You can see here compiler replaces the call to some explicit implementation based on the reference itself.

There are few basic characteristics of Explictely implemented methods.

  1. They are not overridable and cannot be made virtual.
  2. They can only be called with appropriate interface name, as the methods in Vtable is not determined by its name but by the reference it calls for.
  3. You cannot specify any access specifier for the implementation of Explicit method.}
  4. They remain private and does not belong to a member of actual concrete class. For instance, if I remove the normal implementation of GetX and try calling the code below :
    dynamic a1 = new A();
    a1.GetX();

    It produces an exception, as A does not contain the member GetX().
    Now if we see the IL for the implementation :

    So here you can see the explicit declaration defines two important attributes, viz, newslot, virtual and final.

    newslot defines a new pointer in the VTable. Thus it is a completely new method created in vtable that can only be called by reference of the interface explicitely.

    virtual : you must already know virtual means the object could be overridable at runtime.
    final : means sealed.

    Hence it is a sealed method with a new entry in VTable.

  5. They are privately inherited and can be implemented only in the class where the Interface is actually implemented, not in any of its parent. For instance :
    public interface IA
    {
        void GetX();
    }
    abstract class A : IA
    {
    }
    public class B : A
    {
        public void GetX()
        {
            ((IA)this).GetX();
        }
        void IA.GetX()
        {
            Console.WriteLine("New Impleentation");
        }
    }

    The above code produces an exception
    "Inconsistent accessibility: base class 'TestInterfaceApplication.A' is less accessible than class 'TestInterfaceApplication.B'"

    Which means the GetX() method is private to B and cannot be implemented there.
  6. But remember, interface inheritence is supported. Thus the code below compiles fine :

    public interface IA
    {
        void GetX();
    }
    public interface IB : IA
    {
    }
    public class B : IB
    {
        public void GetX()
        {
            ((IA)this).GetX();
        }
        void IA.GetX()
        {
            Console.WriteLine("New Impleentation");
        }
    }

    This is because interface implementation is not actually possible in CLR without marking both of them in concrete class so that the Types can be cast to any of the parent interfaces. So when you specify an Interface implementation, the two interfaces remains as individual types and when you implement the derived interface, it will actually implement the two interfaces for you. Its just a compiler trick.  Lets see the IL.
    So here you can see, if I implement a Derived interface IB from IA, the actual class actually implements both the interface explicitly. 

Practical uses

Explicit interfaces are generally used when you need two implementation of same method or property to co-exist. We generally create Explicit interfaces to specify default behaviour of a class. As explicit methods are actually attached to the interface itself, so at any level of Inherited member, it can be cast easily to get the default implementation (which is in fact not overridable). 

Even though there might be some further cases where it comes really handy, I would like to leave them for you. Post your comments regarding some other practical implementation or something you would like to address to me.

Thanks, I hope you find it interesting.

Happy programming. 




No comments:

Post a Comment

Please make sure that the question you ask is somehow related to the post you choose. Otherwise you post your general question in Forum section.

Author's new book

Abhishek authored one of the best selling book of .NET. It covers ASP.NET, WPF, Windows 8, Threading, Memory Management, Internals, Visual Studio, HTML5, JQuery and many more...
Grab it now !!!