Default interface implementations were introduced in C# 8. Essentially these are interface declarations with bodies.

Where might you use these?

Take this interface:

interface IAnimal
{
    string Name { get; }
    void MakeSound();
}

We can implement this interface with two classes:

A Dog;

public class Dog : IAnimal
{
    public string Name => "Dog";
    public void MakeSound() => Console.WriteLine("Woof");
}

and a Cat;

public class Cat : IAnimal
{
    public string Name => "Cat";
    public void MakeSound() => Console.WriteLine("Woof");
}

We can then use these in a simple application:

void Main()
{
    var dog = new Dog();
    dog.MakeSound();
    
    var cat = new Cat();
    cat.MakeSound();
}

The console will print as follows:

Woof
Meow

Imagine after implementing a bunch of animals, you realized your interface is missing a method. So you add it.

interface IAnimal
{
    string Name { get; }
    void MakeSound();
    void Introduce();
}

If we try and build the project now, we get the following errors:

C:\Projects\BlogCode\DefaultInterface\Cat.cs(5,24): error CS0535: 'Cat' does not implement interface member 'IAnimal.Introduce()' [C:\Projects\BlogCode\DefaultInterface\DefaultInterface.csproj]
C:\Projects\BlogCode\DefaultInterface\Dog.cs(5,24): error CS0535: 'Dog' does not implement interface member 'IAnimal.Introduce()' [C:\Projects\BlogCode\DefaultInterface\DefaultInterface.csproj]

The solution to this problem is to add a default implementation to the new method. Like so:

void Introduce() => Console.WriteLine("Hello");

If we try to build, this time it succeeds.

However, there are a few things to be aware of.

The new method is defined at interface level, and is not available to the concrete implementation.

This is to say you cannot do this:

var dog = new Dog();
dog.MakeSound();
dog.Introduce(); // <-- this is not available

If you really want to invoke it, there are two ways:

1. Cast to the interface

You can cast the object to the underlying interface and then invoke the method on that:

var dog = new Dog();
dog.MakeSound();
((IAnimal)dog).Introduce();

2. Use the interface, not the concrete type

Rather than use the concrete type to manipulate the object, use the interface instead.

IAnimal cat = new Cat();
cat.MakeSound();
cat.Introduce();

If you want a custom implementation of the method, you can provide your own implementation.

public class Mouse : IAnimal
{
    public string Name => "Mouse";
    public void MakeSound() => Console.WriteLine("Squeak");
    public void Introduce() => Console.WriteLine("Squeak! I am a mouse");
}

This can be invoked either as the interface:

IAnimal mouse = new Mouse();
mouse.MakeSound();
mouse.Introduce();

or as the concrete type

var mouse = new Mouse();
mouse.MakeSound();
mouse.Introduce();

The code is in my GitHub

Happy hacking!