Pages

Wednesday, May 25, 2011

Inherit multiple interfaces conflicting method names

To descibe this scenario, I have created a class called ExampleClass that is inheriting two interface IExampleClass1 and IExampleClass2. Both interfaces have same method name and Signature CurrentDateTime(). See the code snippet for them below.


public interface IExampleClass1
{
    string CurrentDateTime();
}
public interface IExampleClass2
{
    string CurrentDateTime();
    string CurrentDateTime(DateTime thisDateTime);
}
public class ExampleClass : IExampleClass1, IExampleClass2
{
    #region IExampleClass2 Members
    public string CurrentDateTime()
    {
        return "Interface 2 : " + DateTime.Now.ToString();
    }
    public string CurrentDateTime(DateTime thisDateTime)
    {
        return "Interface 2 : " + thisDateTime.ToLongDateString();
    }
    #endregion

    #region IExampleClass1 Members
    string IExampleClass1.CurrentDateTime()
    {
        return "Interface 1 : " + DateTime.Now.ToString();
    }
    #endregion
}



ExampleClass ex = new ExampleClass();
lblMessage1.Text = ex.CurrentDateTime();
lblMessage1.Text += "<br />" + ex.CurrentDateTime(DateTime.Now);

IExampleClass1 ex1 = new ExampleClass();
lblMessage2.Text = ex1.CurrentDateTime();

IExampleClass2 ex2 = new ExampleClass();
lblMessage3.Text = ex2.CurrentDateTime();
lblMessage3.Text += "<br />Overload method: " + ex2.CurrentDateTime(DateTime.Now);


OUTPUT:
Interface 2 : 30/08/2012 10:02:20
Interface 2 : 30 August 2012

Interface 1 : 30/08/2012 10:02:20

Interface 2 : 30/08/2012 10:02:20
Overload method: Interface 2 : 30 August 2012

If we inherit these two interfaces into the same class then we will have to implement all the methods defined in these interfaces. Lets see the ways of implementing interface into our class. There are two ways we can implement interfaces into a class.

1. Implement Interface - When we choose this option of implementing interface, we need to define methods name that interface has and need to implement those methods. By default these methods modifiers will be public. This is also called Implicitely implementation of the interface.

#region IExampleClass2 Members
public string CurrentDateTime()
{
    return "Interface 2 : " + DateTime.Now.ToString();
}
public string CurrentDateTime(DateTime thisDateTime)
{
    return "Interface 2 : " + thisDateTime.ToLongDateString();
}
#endregion

2. Implement Interface Explicitely - When you choose this option, you need to define method names that interface has by prefixing the interface name. Notice that there is no access modifier for this method implementation so by default its scope will be internal. Internal is the access modifier for the method or class that is only accessible from the class in same assembly.

#region IExampleClass1 Members
string IExampleClass1.CurrentDateTime()
{
    return "Interface 1 : " + DateTime.Now.ToString();
}
#endregion

If you try to change its access modifier to public in this scenario, you will get "CS0106: The modifier 'public' is not valid for this item" error while running your application. Because there is a public method with the same name and signature already implemented (for IExampleClass2 interface) in the class.

In the above code snippet, you can see that I have instantiated ExampleClass in three different ways. Lets see them one by one.

1. ExampleClass ex = new ExampleClass(); - When we are instantiating the class by specifying the object as the class name, we will be able to call methods for the interface that is implicitely implemented. In this case IExampleClass2.


2. IExampleClass1 ex1 = new ExampleClass(); - If we want to call the method that is explicitely implemented, we need to specify the object as the interface name and instantiate the class then we will be able to call the method of this interface. In this case IExampleClass1.

3. IExampleClass2 ex2 = new ExampleClass(); - You can call methods of the interface that is implicitely implemented by specifying the name of the Interface as the object name (The way we have done in the 2nd point). This will give the same result as the 1st point above.

Now, lets play with the code and remove the implementation of the Interface 1 (IExampleClass1) and then try to run the code. You will see that you are not getting any error even if there is not implementation for the IExampleClass1 interface. This is because the implementation of the method (CurrentDateTime) for IExampleClass2 will be shared for both interfaces. In this case even if we will instantiated the ExampleClass by specifying IExampleClass as the object (point 2 above), we will see that the implementation of IExampleClass2 method is being called.
OUTPUT
Interface 2 : 30/08/2012 10:03:56
Interface 2 : 30 August 2012

Interface 2 : 30/08/2012 10:03:56

Interface 2 : 30/08/2012 10:03:56
Overload method: Interface 2 : 30 August 2012 


Using the cast method
ImplementationClass obj = new ImplementationClass();
IInterface1 if1 = (IInterface1)obj;
if1.MyMethod();

IInterface2 if2 = (IInterface2)obj;
if2.MyMethod();

No comments:

Post a Comment