Skip to main content

Interfaces in C# 8.0 gets a makeover

Even today when I am in deep sleep and someone wakes me up and asks “Can C# Interfaces have any access modifiers?” My answer would be “Hell, NO“. As this is what stored very deep in my mind and being a programmer have learned this over the years. But the time has come to erase those memories as with C# 8.0, interfaces are getting a whole makeover. Therefore, our interfaces knowledge also needs to be revisited. C# 8.0 introduces a new feature called “Default implementations in interfaces” and this will change a lot of things. In this post, we’ll see this new feature and what you need to know now about interfaces.

Default Implementations in Interfaces

Before, we take a look at this new feature, let’s take a step back and summarize what we know till today about Interfaces in C#.

What do we know about Interfaces in C# till today

  • An interface only contains declarations of methods, properties, indexers, and events.
  • An interface cannot include private, protected, or internal members.
  • An interface cannot contain fields.
  • By default, all the members of an interface are public and abstract. C# will give a compile-time error if used ‘public’ keyword explicitly. In fact, we cannot use any access modifiers with interface members.
    interface IRepository
    {
        //Compile-time error CS0106 The modifier 'public' is not valid for this item.
        public void Add(); 
    }
    

With C# 8.0, things are changing with respect to Interfaces. First, let me give you a brief idea about a new feature called “Default implementations in interfaces” and later we’ll see what changes w.r.t. Interfaces.

Let’s say you have an interface in your application and many classes implement it. If you add a new member to it,

  • Either you must update all the classes to support the new member.
  • Or you create an extended interface with a new method and this interface will inherit from the existing interface. Like,
    interface ICar
    {
        void GetSpeed();
        void GetMileage();
    }
    
    interface IInternetCar : ICar
    {
        void SendCommand();
    }
    
  • The extended interface is the answer for such a problem. But with new methods and functionalities, the extended interface list can grow and may become unmanageable. C# 8.0 addresses this by Default implementations in interfaces feature. This feature allows you to write an implementation of any method. This is useful in situations where you can add new members to interface with a default implementation, without breaking the existing implementation. Like,

    interface ICar
    {
        void GetSpeed();
        void GetMileage();
        public void SendCommand() {
          //Send the Command.
        }
    }
    

    Now, you don’t have to write a new interface and change the existing implementation. However, this default implementation will be available from an instance of the interface. Like (see 2 and 3),

    default implementations in Interfaces in C# 8

    Here, the classes are free to override the default implementation. If any class overrides it, then its own implementation will be called. So, if the class MorrisGarage implements the SendCommand method, then its implementation will be called.

    public class MorrisGarage : ICar
    {
        public void GetMileage()
        {
            Console.WriteLine("10 KM Per Liter"); 
        }
    
        public void GetSpeed()
        {
            Console.WriteLine("200 KMPH");
        }
    
        public void SendCommand()
        {
            Console.WriteLine("Command Sent via Morris Garage Class");
        }
    }
    

    Below is the result.

    default implementations in Interfaces

    According to Microsoft, the principal motivations for this feature are:

  • Default interface methods enable an API author to add methods to an interface in future versions without breaking source or binary compatibility with existing implementations of that interface.
  • The feature enables C# to interoperate with APIs targeting Android (Java) and iOs (Swift), which support similar features.
  • As it turns out, adding default interface implementations provides the elements of the “traits” language feature (https://en.wikipedia.org/wiki/Trait_(computer_programming)). Traits have proven to be a powerful programming technique (http://scg.unibe.ch/archive/papers/Scha03aTraits.pdf).
  • What do we need to know now about Interfaces in C#

    • Interfaces can now have the default implementation of methods.
    • Interfaces can now have Private members.
      public interface ICar
      {
          private void Initialize()
          {
              //Initialize the Command Center
          }
          void GetSpeed();
          void GetMileage();
          public void SendCommand()
          {
              Initialize();
              Console.WriteLine("Command Sent via Interface");
          }   
      }
      
    • Interfaces can now also have static members. This is used for parameterization of the default implementation.
      public interface ICar
      {
          private static string commandName = "LOCK_CAR";
          private void Initialize(string cName)
          {
              commandName = cName;
              //Initialize the Command Center
          }
          void GetSpeed();
          void GetMileage();
          public void SendCommand(string cName)
          {
              Initialize(cName);
              Console.WriteLine("Command Sent via Interface");
          }
      }
      

      You can read this post for more information. Remember, you still can’t define instance member in the interface.

    • Interfaces can also have protected members. They are not accessible by the derived class, but via the derived interface.
      public interface ICar
      {    
          public void SendCommand()
          {        
              Console.WriteLine("Command Sent via Interface");
          }
          protected void SendCriticalCommand()
          {
              Console.WriteLine("Critical Command Sent via Interface");
          }       
      }
      
      public interface IAnotherCar : ICar
      {
          public void Send(bool bCritical)
          {
              if (bCritical)
                  this.SendCriticalCommand();
              else
                  Console.WriteLine("Command Sent via Morris Garage Class");
          }
      }
      

      If the class wants to implement the protected member, it has to be done via implementing interface explicitly.

    • Interfaces can also have virtual members, but the class can’t override the method. An interface can only override it.
      public interface ICar
      {
          public virtual void SendCommand()
          {        
              Console.WriteLine("Command Sent via Interface");
          }
      }
      
      public interface IAnotherCar :ICar
      {
          void ICar.SendCommand()
          {
              Console.WriteLine("Command Sent via another Interface");
          }
      }
      
      class MorrisGarage: ICar, IAnotherCar 
      {
          
      }
      
      class Program
      {
         static void Main()
         {
            ICar mg= new MorrisGarage();
            mg.SendCommand(); //Calls the virtual implementation.
      
            IAnotherCar mgOverridden = new MorrisGarage();
            mgOverridden.SendCommand(); //Calls the overridden implementation.
        }
      }
      

      You can also use the abstract methods, but using the abstract keyword doesn’t make any difference as classes need to implement the interface methods (whether or not marked as abstract).

    You must be thinking by now, “Thank God. Interfaces and abstract classes are sort of same now and this interview question is no longer valid.” Well, I leave that to your wisdom.

    Remember, it’s an optional feature, and no one is forcing you to use this.

    Reference Posts:

  • Default implementations in interfaces
  • Interfaces in C# 8 are a Bit of a Mess
  • Update interfaces with default interface members in C# 8.0
  • Default Interface Methods in C# 8
  • Summary

    To summarize, the default implementation is a useful feature as it allows developers to release new changes without breaking the existing implementation. But this has received mixed feedback from the developers. It has already received a lot of criticism, then there are others who are thrilled about it. Java and Scala already have this feature and C# is also moving in that direction from Oops to functional programming. In the beginning, it’s difficult to adapt to new things, but in the long run, it starts to make sense.

    Thank you for reading. Keep visiting this blog and share this in your network. Please put your thoughts and feedback in the comments section.

    PS: If you found this content valuable and want to return the favour, then Buy Me A Coffee

    8 thoughts to “Interfaces in C# 8.0 gets a makeover”

    1. This language feature has to do with Mixins as a pattern introduced/available in other languages, namely, JavaScript or available as traits/protocols in Scala, Java, Objective C and more modern one like Swift which also do not support state variables as Mixins does in JavaScript.

    2. I’m sorry but if you have to have a disclaimer such as “Remember, it’s an optional feature, and no one is forcing you to use this.” then that might be a sign that this is, at the very least, a very questionable design decision.

      I also don’t like the wording at the end, “In the beginning, it’s difficult to adapt to new things, but in the long run, it starts to make sense.” This implies that companies know what is best for me and somehow I don’t. I like to make my own decisions on what I like and don’t like. I’ve been programming now for almost 2 decades and I believe I am more than qualified to state my own opinion. If a design decision is a bad one, time will not change this.

      You also state that the difference now between an abstract class and an interface is left to our own wisdom. I would retort by saying there really is not any difference now. I think the restrictions of an interface are for a reason and removing these restrictions removes the purpose of an interface. To me this is like saying, “hey look I improved our Stack implementation. Now you can pop from both ends!” This is really not a step in the right directions and this is coming from someone who loves C#. I think if you already have a large code base and you want to add a method to your interface, either suck it up and implement it in the classes that implement the interface, or change the interface into an abstract class. An “interface” by definition is all about method signatures without implementation. This new feature distorts that definition.

      1. I actually greatly prefer the system Hungarian notation convention of prefixing interfaces with an “I”. When I code in Java, I miss this convention. This helps me to know which are interfaces and which are classes without having to go to their definitions. To each his own, but I would like this convention to live on.

    3. I’m interested as to what possible advantages there are in using default implementation in an interface as opposed to an abstract base class?

      Plus doesn’t this open C# interfaces to the issues with multiple class inheritance? What happens when a class inherits two interfaces which both have a default implementation of the same method? I’m hoping you’d get a compile error.

      So why aren’t the concerns which saw the C++ multiple class inheritance feature deliberately prohibited in CLI languages not a concern with this feature? Have we just forgotten how crap this was?

      https://devblogs.microsoft.com/csharpfaq/why-doesnt-c-support-multiple-inheritance/

      1. I’ve only recently been programming with OO a lot. So i’m not sure what the drawbacks of multiple class inheritance are. But at the moment, this new “Default implementations in interfaces” solves a problem i’m having because of C# not having pure multiple class inheritance.

    Leave a Reply

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