Implement explicit interface members in a class
In C#, explicit interface implementation allows a class to implement interface members in a way that they're only accessible through the interface, not the class instance. This is useful when a class implements multiple interfaces with members that have the same signature.
Multiple interfaces in a class
A class in C# can implement multiple interfaces, allowing it to inherit behavior from various sources. The ability to combine multiple interfaces is crucial because C# doesn't support multiple inheritance of classes. Implementing multiple interfaces allows a class to have different features and ensures it follows the rules set by those interfaces.
- Interfaces define a group of related functionalities.
- A class or struct must implement all members of the interfaces it inherits.
- Interfaces can contain methods, properties, events, and indexers.
Here are two simple interfaces for our example:
public interface IEnglishDimensions
{
float Length();
float Width();
}
public interface IMetricDimensions
{
float Length();
float Width();
}
Explicit interface members
In C#, a class can inherit from only one class but can implement multiple interfaces. This is especially important when several interfaces have the same member names. To avoid confusion, we use explicit interface implementation.
Explicit interface implementation ensures that each member of an interface has a unique implementation, preventing conflicts. It also clarifies which interface a member belongs to when a class implements two or more interfaces with the same member names. Explicit interface implementation allows a class to fulfill the requirements of multiple interfaces, providing diverse functionalities.
To explicitly implement a member of an interface, you add the interface name and a period before the member name. Here's an example:
public class Box : IEnglishDimensions, IMetricDimensions
{
float IEnglishDimensions.Length()
{
return 30.0f;
}
float IEnglishDimensions.Width()
{
return 20.0f;
}
float IMetricDimensions.Length()
{
return 76.2f;
}
float IMetricDimensions.Width()
{
return 50.8f;
}
}
In this code, the Box class is implementing two interfaces: IEnglishDimensions and IMetricDimensions. Both interfaces have members named Length and Width. To avoid confusion, each member is explicitly linked to its interface.
Note
Explicitly implemented interface members don't have access modifiers like public, private, etc. They can only be accessed through an instance of the interface, not the class. This means you can't call Box.Length(), but you can call IEnglishDimensions.Length() if you have an instance of Box that's being treated as an IEnglishDimensions.
Use explicit interface members
You need to create instances of the interfaces and call their members to execute and test code that utilizes explicit interface members. This ensures that the correct implementation is invoked based on the interface type.
Box box = new Box();
IEnglishDimensions eDimensions = box;
IMetricDimensions mDimensions = box;
Console.WriteLine($"Length in inches: {eDimensions.Length()}");
Console.WriteLine($"Width in inches: {eDimensions.Width()}");
Console.WriteLine($"Length in centimeters: {mDimensions.Length()}");
Console.WriteLine($"Width in centimeters: {mDimensions.Width()}");
In this example, the Box class instance is cast to both IEnglishDimensions and IMetricDimensions to access the explicit interface members. The output displays the dimensions in both English and metric units.
Length in inches: 30
Width in inches: 20
Length in centimeters: 76.2
Width in centimeters: 50.8
In C#, you can implement multiple interfaces in a class, using explicit interface implementation to resolve naming conflicts when members have the same signatures. Explicitly implemented members are accessed through the interface instance, not the class instance, ensuring proper functionality and avoiding ambiguity. This approach enhances code maintainability by clearly defining the intended behavior for each interface, making the codebase easier to understand and extend.