Sunday, October 30, 2011

Explicit Interface C#


In this article we will see how to explicitly implement interface members and how to access those members from the interface instances.
 
One of the challenges we face with interfaces is that they may include that have the same name as existing class member or any other interface that you may be implementing. Hence we use explicit interface implementation to distinguish the interface methods that would otherwise conflict. When a member is explicitly implemented, it cannot be accessed through a class instance, but only through an instance of the interface.
 
Let us look at an example where we have two interfaces and we will implement the same in our class:
 
interface Interface1
    {
        void InterfaceMethod();
    }

    interface Interface2
    {
        void InterfaceMethod();
    }

    class MyClass : Interface1, Interface2
    {
        public void InterfaceMethod()
        {
            Console.WriteLine("MyClass.InterfaceMethod()");
        }
    }

In this case, InterfaceMethod is a public class member that implicitly implements a member of both interfaces. InterfaceMethod() can be invoked through either interface or through the class itself as follows:
 
MyClass mclass = new MyClass();
Interface1 minterface1 = (Interface1)mclass;
Interface2 minterface2 = (Interface2)mclass;

minterface1.InterfaceMethod();
minterface2.InterfaceMethod();
mclass.InterfaceMethod();

 
The output from this code is:
 
MyClass.InterfaceMethod()
MyClass.InterfaceMethod()
MyClass.InterfaceMethod()

 
This works fine if you want InterfaceMethod() to do the same thing in both interfaces. But in real scenarios methods which are in different interfaces have unique purpose and implementation, so here we will see the implementation of Explicit interface by just using its fully qualified name.
 
Let change our MyClass code a little like the one below:
 
class MyClass : Interface1, Interface2
    {
        public void InterfaceMethod()
        {
            Console.WriteLine("MyClass.InterfaceMethod()");
        }

        void Interface1.InterfaceMethod()
        {
            Console.WriteLine("Interface1.InterfaceMethod()");
        }
    }

 
Now when we run our application we get the following output:

Interface1.InterfaceMethod()
MyClass.InterfaceMethod()
MyClass.InterfaceMethod()
 
Remember that when an interface method is explicitly implemented, we cannot access that as a public member of the class. The only way to access it is through the interface.
 
Lets modify the MyClass to check this:
 
class MyClass : Interface1, Interface2
    {
        void Interface1.InterfaceMethod()
        {
            Console.WriteLine("Interface1.InterfaceMethod()");
        }
    }

 
Let's run our program and check the output:
 
We get a compile error:
 
MyClass does not contain a definition for 'InterfaceMethod' and no extension method 'InterfaceMethod' accepting a first argument of type MyClass could be found (are you missing a using directive or an assembly reference?
 
We get this error because the explicit implementation of Interface1.InterfaceMethod()
 
hides from the class. The only way to call Interface1.InterfaceMethod() now is through MyClass minterface1 interface.
 
Let's look at an example where we want to call default methods and implement the methods normally from one interface, and explicitly implement the methods from another interface:
 
MyClass implementation is changed to show this example:
 
interface Celsius
    {
        void GetTemp();
    }

    interface Fahrenheit
    {
        void GetTemp();
    }

class MyClass : Celsius,Fahrenheit
    {
        public void GetTemp()
        {
            Console.WriteLine("Get Celsius Temp");
        }

        void Fahrenheit.GetTemp()
        {
            Console.WriteLine("Get Fahrenheit Temp");
        }
    }

 
In this case, you can access the Celsius GetTemp from the class instance and access the Fahrenheit  GetTemp from the interface instance:
 
MyClass mclass = new MyClass();
Fahrenheit mfahrenheit  = (Fahrenheit)mclass;

mclass.GetTemp();
mfahrenheit.GetTemp();

 
Following is the output in the above case:
 
Get Celsius Temp
Get Fahrenheit Temp

 
Hope you liked this article.
 
Coder-Forever!

No comments:

Post a Comment