Default Interface Methods in C# 8.0

Introduction

 
We never had a provision to define method body in C# interfaces, but C# 8.0 brings you the ability to define method body into your interface. In C# 8 on .NET Core 3.0, you can define an implementation to an interface. The main scenario is to add new members to an existing interface which is already in production.
 
Let's see how the old C# interface used to be before this feature.
  1. public class Training    
  2. {    
  3.     public Training(string name, string cost)    
  4.     {    
  5.             Name = name;    
  6.             Cost = cost;    
  7.     }    
  8.     
  9.     public string Name { getset; }    
  10.     
  11.     public string Cost { getset; }    
  12. }    
  13.     
  14. interface ITrainingService      
  15. {      
  16.     IList<Training> Trainings { get; }      
  17.       
  18.     void AddTraining(string name, string cost);      
  19.       
  20.     void AddTraining(Training training);      
  21. }   
Here, we have two interface methods which you are forced to implement in your derived classes, but in C# 8.0, you can define method implementation directly inside interface which allows you to write less code during implementation and common code of different derived classes can be written directly in the interface, an alternate of abstract class.
 
In this example, if you want to add a training object which is going to common by adding a name, cost or by training object. If more than one class is implementing this interface, you have to write the same implementation either by creating a base abstract class or possibly in both derived classes. Now, you can use this new C# 8.0 feature and write the kind of common implementation directly in the interface. 
 
Upgrade default interface methods
  1. interface ITrainingService      
  2. {      
  3.     IList<Training> Trainings { get;  }      
  4.       
  5.     void AddTraining(string name, string cost) => AddNewTraining(name, cost);      
  6.       
  7.     void AddTraining(Training training) => AddTraining(training.Name, training.Cost);      
  8.       
  9.     public string GetTrainingString(Training item)    
  10.     {      
  11.         return $" Traning {item.Name} has {item.Cost}";      
  12.     }      
  13.       
  14.     protected void AddNewTraining(string name, string cost)      
  15.     {      
  16.         Trainings.Add(new Training(name, cost));      
  17.     }      
  18. }       
  1. public class TrainingService : ITrainingService    
  2. {    
  3.     public TrainingService()    
  4.     {    
  5.         TrainingData = new List<Training>();    
  6.         TrainingData.Add(new Training("c# 8.0""$20"));    
  7.         TrainingData.Add(new Training("JS""$40"));    
  8.    }    
  9.     
  10.    public IList<Training> Trainings => TrainingData;    
  11.     
  12.    private static IList<Training> TrainingData;    
  13. }    
Implementation of Interface. Here you may notice that implementation of these methods are not required to implement in the derived class.
 
Use of this interface in main(),
  1. static void Main(string[] args)    
  2. {    
  3.     ITrainingService trainingService = new TrainingService();    
  4.     trainingService.AddTraining("time mamangement""$20");    
  5.     trainingService.AddTraining(new Training("other""$0"));    
  6.     
  7.     foreach (var item in trainingService.Trainings)    
  8.     {    
  9.         Console.WriteLine(trainingService.GetTrainingString(item));    
  10.     }    
  11.     
  12.     Console.ReadKey();    
  13. }    
Calling AddTraining() interface member implementation direclty which does not have any respective class member which execute the interface implementation.
 

Conclusion

 
Here, we learned how to upgrade our old interface safely with new member implementation directly inside the interface.