Implicit Interface Implementation vs. Explicit Interface Implementation
Introduction
In C#, you can implement an interface implicitly or explicitly. In most of cases, we are using implicit interface implementation, i.e., you have a method with the same signature of the interface.
internal interface IMyInterface
{
void SayHello();
}
internal class ImplicitImplementation : IMyInterface
{
public void SayHello()
{
Console.WriteLine("ImplicitImplementation says hello.");
}
}
An explicit interface implementation is defined by prefixing the interface method with the name of the interface and a period. The method is only accessible through the specified interface.
internal class ExplicitImplementation : IMyInterface
{
void IMyInterface.SayHello()
{
Console.WriteLine("ExplicitImplementation says hello.");
}
}
Notice that the method does not have public access modifier since it is only accessible through interface.
IMyInterface v1 = new ExplicitImplementation();
v1.SayHello();
When you have to use Explicit Interface Implementation?
In the following situation, you would have to use Explicit Interface Implementation:
- Your class implements two interfaces that have same method signature.
internal interface IControl
{
void Paint();
}
internal interface ICanvas
{
void Paint();
}
internal class MyControl : IControl, ICanvas
{
void IControl.Paint()
{
Console.WriteLine("IControl.Paint()");
}
void ICanvas.Paint()
{
Console.WriteLine("ICanvas.Paint()");
}
}
var control = new MyControl();
((IControl)control).Paint();
((ICanvas)control).Paint();
2. You don’t want to expose the interface method on the class type. You want to user to cast the type to interface to access the method.
internal class ExplicitImplementation : IMyInterface
{
void IMyInterface.SayHello()
{
Console.WriteLine("ExplicitImplementation says hello.");
}
}
// The following two lines would cause compile error
// 'ExplicitImplementation' does not contain a definition for 'SayHello'
ExplicitImplementation v1 = new ExplicitImplementation();
v1.SayHello();
// The following lines are OK
IMyInterface v1 = new ExplicitImplementation();
v1.SayHello();
In the above code, the SayHello() method is not accessible through object instance. You have to cast it into interface in order to access it.
Inheritance
Things will get complicated when the inheritance gets involved. Assume both your base class and sub class have to implement same interface (implicitly or explicitly), which implementation is called in different scenario? There are many combinations. We will only discuss two scenarios here.
Both Base Class and Sub Class use Implicit Interface Implementation
internal class ImplicitImplementation : IMyInterface
{
public void SayHello()
{
Console.WriteLine("ImplicitImplementation says hello.");
}
}
internal class ImplicitImplementationSubClass : ImplicitImplementation, IMyInterface
{
public void SayHello()
{
Console.WriteLine("ImplicitImplementationSubClass says hello.");
}
}
ImplicitImplementation v3 = new ImplicitImplementation();
v3.SayHello();
ImplicitImplementation v4 = new ImplicitImplementationSubClass();
v4.SayHello();
IMyInterface v5 = new ImplicitImplementationSubClass();
v5.SayHello();
// Output
ImplicitImplementation says hello.
ImplicitImplementation says hello.
ImplicitImplementationSubClass says hello.
Here the output are a bit interesting: The first one is obvious. The second and the third one worth some explanation.
For the second one (v4), the runtime calls the interface implementation in base class ImplicitImplementation because when both base and sub class implement the same interface implicitly, the sub class implementation hides the base class implementation.
For the third one (v5), the runtime calls the interface implementation in sub class because the v5 instance is constructed from the sub class and casted to the interface.
Both Base Class and Sub Class use Explicit Interface Implementation
internal class ExplicitImplementation : IMyInterface
{
void IMyInterface.SayHello()
{
Console.WriteLine("ExplicitImplementation says hello.");
}
}
internal class ExplicitImplementationSubClass : ExplicitImplementation, IMyInterface
{
void IMyInterface.SayHello()
{
Console.WriteLine("ExplicitImplementationSubClass says hello explicitly.");
}
public void SayHello()
{
Console.WriteLine("ExplicitImplementationSubClass says hello implicitly.");
}
}
IMyInterface v1 = new ExplicitImplementation();
v1.SayHello();
IMyInterface v2 = new ExplicitImplementationSubClass();
v2.SayHello();
ExplicitImplementationSubClass v2_1 = new ExplicitImplementationSubClass();
v2_1.SayHello();
/// Output
ExplicitImplementation says hello.
ExplicitImplementationSubClass says hello explicitly.
ExplicitImplementationSubClass says hello implicitly.
The output here are more clear to understand. The explicit interface implementation can only be accessible by interface. Depending on what real object instance is casted to interface, the runtime would trigger the interface implementation of that object instance.
You can implement the interface both implicitly and explicitly. The runtime will call the proper implementation depending on whether you use interface or class object to call it. The third output (v2_1) demonstrate when calling from class object, the runtime will choose the implicit interface implementation.
Happy coding!