This article is for Object-Oriented Programming (OOP) beginners.
An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Interface member. In C# multiple inheritance is achieved with the help of Interfaces.
Therefore, if the Development Team is large or 3rd-party vendors are involved, then it may possible that two team members may end up creating two different Interfaces with the same method name. Consequently, as a developer you may have to implement both these Interfaces in one Class.
Scenario: So let’s assume that –
You have two different Interfaces let’s say ICustomer and IVendor. Both the Interfaces have a method with same name let's say GetData().
GetData() from ICustomer would return the list of customer names while GetData() from IVendor would return the list of vendor names. In the data access layer, a single class CompanyDAL implements both these Interfaces.
See attached Code Snippet for Interface definitions –
using System.Collections.Generic;
namespace ExplicitInterfacesSite
{
// Simple interface for Vendor class
public interface IVendor
{
// Return the list of vendor names
List<string> GetData();
}
// Simple interface for customer class
public interface ICustomer
{
// Return the list of customer names.
// This function name is conflicting with IVendor's GetData.
List<string> GetData();
// Another method, which is not conflicti
string GetCustomerAddress(int customerId);
}
}
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
Select allOpen in new window
Solution:
While implementing the Interface in a class, we must provide the concrete implementation to each of the Interface member. For non-conflicting Interface members, we can just write the member name and provide the implementation. But for any method which is common in both the Interfaces, the member should be implemented explicitly in the class.
By explicit, I mean the method name should be prefixed with <InterfaceName.>. In our case it is like IVendor.GetData () or ICustomer.GetData().
See Code Snippet –
using System.Collections.Generic;
namespace ExplicitInterfacesSite
{
public class CompanyDAL : IVendor, ICustomer
{
#region IVendor Members
List<string> IVendor.GetData()
{
// Implement your logic to get the list of Vendor Names
return new List<string>() {"Vendor1", "Vendor2", "Vendor3"};
}
#endregion
#region ICustomer Members
// This is how we should implement the conflicting method, explicitely
List<string> ICustomer.GetData()
{
// Implement your logic to get the list of Customer Names
return new List<string>() {"Customer1", "Customer2"};
}
// No need of Interface.MethodName as there is no conflict.
public string GetCustomerAddress(int customerId)
{
return "Dummy Customer Address";
}
#endregion
}
}
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
Select allOpen in new window
And when we want to call that method, we need to typecast the class object to the desired Interface.
I have added an .aspx page in the project to demonstrate this. It just prints the list of vendors and customers.
See the attached Code Snippet –
using System;
using System.Collections.Generic;
namespace ExplicitInterfacesSite
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// Create the object
CompanyDAL expliciteObj = new CompanyDAL();
// Can directly call method, whose name is not confliciting
expliciteObj.GetCustomerAddress(1);
// Cast the object to the interface first and then call the conflicting method.
// Here we are calling the GetData() method of IVendor class.
List<string> lstVendors = (expliciteObj as IVendor).GetData();
Response.Write("Vendor List:</br>");
foreach (string vendorName in lstVendors)
{
Response.Write(vendorName);
Response.Write("</br>");
}
// Cast the object to the interface first and then call the conflicting method.
// Here we are calling the GetData() method of ICustomer class.
List<string> lstCustomers = (expliciteObj as ICustomer).GetData();
Response.Write("Customer List:</br> ");
foreach (string customerName in lstCustomers)
{
Response.Write(customerName);
Response.Write("</br>");
}
}
}
}
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
Select allOpen in new window
Let's look at the below code line carefully –
I first typecast the expliciteObj to the Interface type, and then called the conflicting method. By doing this we are able to remove the conflict/ambiguity in the method name. This would return a list of string. It should contain below strings (vendor names):
"Vendor1", "Vendor2" and "Vendor3".
The same way in the below code line –
expliciteObj is first converted to ICustomer and then called the method GetData. This call would return a list of customer names. In our case it should be:
"Customer1" and "Customer2".
Summary: In the above article I tried to explain how to achieve multiple Interface inheritance in C# and how to handle conflicting methods present in more than one Interface. I hope you will enjoy reading this article. Waiting for your feedback.