Vaughan Reid's blog

Understanding default interface members in .NET Core

A new feature in C# 8.0 and .NET Core 3.0 is that of default interface members. The motivation for it is where authors of a public interface would like to add functionality to an existing interface but don’t want to force all the consuming code to implement it. You are able to add a default implementation to your new method so that consuming code isn’t forced to.

In my opinion, its a little dangerous since it blurs the line between interfaces and abstract classes but still good to know it is available.

An example is if I have an ICalculation interface that someone else has implemented with a Calculation class.

public interface ICalculation
{
	int Add(int first, int second);
}

public class Calculation : ICalculation
{
	public int Add(int first, int second)
	{
		return first + second;
	}
}

At a later point I decide that its really important that the ICalculation contract can also add 3 numbers. I can now update my interface with a default implementation to not break the Calculation class when they update to latest.


public interface ICalculation
{
	int Add(int first, int second);

	int Add(int first, int second, int third) => Add(Add(first, second), third);
}

When they update, it will still compile. They won’t even need to be aware that I had that change.

One strange side effect is that you will only see the new member if your variable is the interface and not the derived class. As an example below, you can call Add(1,2,3) on iCalc but not on calc.


public void Run()
{
	ICalculation iCalc = new Calculation();
	Calculation calc = new Calculation();

	iCalc.Add(1, 2, 3);

	//Not implemented on derived class
	//calc.Add(1, 2, 3);
}