Default interface methods in C# 8.0

Do you remember your interview days when you answered that interfaces cannot have implementations. Its time that you change this answer. In this post, we will look into a really new feature starting with C# 8.0 where you can define a concrete implementation of an interface member. Let’s see how we can go about learning default interface methods in C# 8.0.

Prerequisites

You will need to download the .Net Core 3.0 SDK or if you are using Visual Studio, then you will need to use Visual Studio 2019 16.3 along with the C# 8.0 compiler.

Introducing Default Interface Methods in C# 8.0

Starting with .Net 3.0 which includes C# 8.0, when we declare an interface member we can also add a default implementation. This new feature now makes the old definition obsolete that ‘all classes using an interface must provide an implementation for all its members’. This implementation can be defined while declaring an interface member. One example scenario is that we can add members to an existing interface which has been already implemented by client functionality.

In this post we will learn how to add method implementations thereby extending interfaces safely

Example

Assume a vendor who has already developed the following simple functionality for their clients. The clients have order based applications which have implemented the following interfaces from the vendor.

The User interface

public interface IUser
{
    IEnumerable <IOrder> PreviousOrders{ get; }
    DateTimeDateJoined { get; }
    DateTime? LastOrder { get; }
    string Name { get; }
    IDictionary <DateTime, string>  Reminders { get; }
}

The Order interface

public interface IOrder
{
    DateTime Purchased { get; }
    decimal Cost { get; }
}

The business intention behind the above functionality was to record the existing user experiences by tracking their purchasing history.

Now a time came when the above functionality had to be updated.

Few of the clients, wanted to offer a Discount rate for some of the users who have already made 5 purchases. This Discount should be applied as a property of every user. But this Discount could vary upon user to user.

C# 7.0 and earlier

The above functionality could be achieved by adding a new method for calculating the Discount. But this new interface member would also break all other applications since the above interfaces were already implemented. And also they all needed to implement the new method. Hence the developers of the vendor claimed that the above new functionality could introduce breaking changes in existing applications.

C# 8.0

Now with C# 8.0, developers could upgrade their existing interfaces with a new method and a default implementation. This allows the developers to upgrade existing interfaces and still enabling calling classes to override the default implementation.

Default Interface Methods

In order to provide discount to existing users the developers included a default implementation of the new method in the earlier User interface as below:

public decimal CalculateDiscount()
{
    if (PreviousOrders.Count() > 5))
    {
        return 0.25m;
    }
    return 0;
}

Now the above new functionality can be tested by existing application are follows:

// Calculate discount:
IUser existingUser = u;
Console.WriteLine($"Current discount: { existingUser.CalculateDiscount() }");

Notice the cast from IUser is mandatory. The existingUser class doesn’t need to provide an implementation for CalculateDiscount thats provided by the IUser interface. Hence to call any method declared and implemented in the interface, it should be of the type of the interface, IUser as shown in the above example.

Other features included in C# 8.0 Interfaces

  • Interfaces can now include static members
  • Interfaces can also contain methods and fields
  • Access modifiers are also enabled

You can try out all the above features but remember to upgrade to VS 2019 16.3 and .Net Core 3.0 SDK.

Summary

All the new features mentioned in this post indicate that interfaces in C# 8.0 can be updated safely when a default implementation is provided for new members. Hence for any new functionality, developers need not worry on any breaking changes due to updates to an interface. Keep visiting this blog and keep learning.

Hitesh Boricha

I have a little over a decade experience in the IT industry. Having worked in various roles in this industry, I am passionate about technology.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.