Expilicit Interface Implementation

There is always the possibility you might implement interfaces that contain identical members and therefore, have a name clash to contend with.

class Octagon : IDrawToForm, IDrawToMemory
 {
     public void Draw()
     {
         Console.WriteLine("Drawing the Octagon!");
     }
 }
public interface IDrawToForm
 {
     void Draw();
 }
public interface IDrawToMemory
 {
     void Draw();
 }
 
Octagon oct = new Octagon();
// explicitly.
 ((IDrawToMemory)oct).Draw();
if (oct is IDrawToMemory dtm)
 {
     dtm.Draw();
 }

When using explicit interface implementation syntax:

class Octagon : IDrawToForm, IDrawToMemory
 {
     void IDrawToMemory.Draw()
     {
         throw new NotImplementedException();
     }
   void IDrawToForm.Draw()
     {
         throw new NotImplementedException();
     }
 }

The syntax;

returnType InterfaceName.MethodName(params)

Note that when using this syntax, you do not supply an access modifier, explicitly implemented members are automatically private.

// Error! No access modifier
public void IDrawToMemory.Draw()
 {
     throw new NotImplementedException();
 }

Designing Interface Hierarchies

Interfaces can be arranged in an interface hierarchy. Like a class hierarchy when an interface extends an existing interface, it inherits the abstract members defined by the parent (or parents). Prior to C# 8, derived interfaces never inherit true implementation. Rather, a derived interface simply extends its own definition with additional abstract members. In C# 8, derived interfaces inherit the default implementations as well as extend the definition and potentially add new default implementation.

public interface IDrawable
 {
     void Draw();
 }
public interface IAdvancedDraw : IDrawable
 {
     void DrawInBoundingBox(int top, int left, int bottom, int right);
     void DrawUpsideDown();
 }
public class BitmapImage : IAdvancedDraw
 {
}

Interface Hierarchies with Default Implementations

When interface hierarchies also include default implementations, downstream interfaces can choose to carry the implementation from the base interface or create a new default implementation.

public interface IDrawable
 {
     void Draw();
     int TimeToDraw() => 5;
 }
 
BitmapImage myBitMap = new BitmapImage();
// This code does not compile
myBitMap.TimeToDraw();

If a downstream interface wants to provide its own default implementation, it must hide the upstream implementation.

public interface IAdvancedDraw : IDrawable
 {
     …
    new int TimeToDraw() => 15;
 }

Then BitmapImage class can implement this method.

public class BitmapImage : IAdvancedDraw
 {
     public new int TimeToDraw() => 15;
…
}
 
BitmapImage myBitMap = new BitmapImage();
Console.WriteLine(myBitMap.TimeToDraw());
Console.WriteLine(((IDrawable)myBitMap).TimeToDraw());
Console.WriteLine(((IAdvancedDraw)myBitMap).TimeToDraw());