Default interface implementation in C# 8

Akos Nagy
Jun 12, 2019

A while back the preview version of the last big feature of C# 8 came out: default interface implementation. To be honest, I'm not really a fan of this new option and I have been pretty busy, so I didn't really have the time to check it out, nor did I really want to. But I have created posts on all other new language features (you can check them out here.), so I decided not to miss out this last one.

Default interface implementation

The feature is just what the name suggest: now you can add a default body to the methods you define in your interfaces:

public interface ISuperInterface
{
  void DoSomething()
  {
    Console.WriteLine("Doing something");
  }
}

And then, when you create a class, you are no longer required to implement this method, instead, you can just "inherit" the implementation from the interface:

public class SuperImplementation : ISuperInterface
{
  // this now compiles, even without the interface method present
}

And then, here's how you use it:

ISuperInterface x = new SuperImplementation();
x.DoSomething();

Note that you have to access the object through an interface reference. Default implementations are not available on the actual type reference, just like with explicit interface implementation.

Also, you can now specifiy a visibility for the interface method:

public interface ISuperInterface
{
  private void DoSomething()
  {
    Console.WriteLine("Doing something");
  }
}

Now, calling the method does not compile. I would say cool, but I don't really like the feature altogether.

I'm not really sure how this is implemented, I guess I should have gone throught the LDM notes, but again, I wasn't really enthusiastic about this feature. I did try to trick it though: I put the interface into a separate DLL, built the DLL with the class in it, then changed the interface in the DLL and built it separately. Finally I copied the DLL of the new version of the interface next to DLL of the class to see if the method body was part of the interface or the class. I was relieved to see that it is actually part of the interface and not the class, so at least this works (unlike in the case of default parameter values).

Verdict

So the feature is quite solid, even if I don't like it. Why? Easy: just like pattern matching, it makes writing bad code a language-supported thing. The mainstream communication with this feature is that it allows you to add new methods to your interfaces without breaking existing implementations. Well, here's the sad truth: adding new methods to an interface should break existing implementations. That's one of the main charateristics of an interface: it acts as a contract. You can't just change the contract and enforce the previously involved parties to go along with it. Even if the explicit nature makes it a little more acceptable.

And here's another thing: you could do more or less the same thing with extension methods as well. Of course they were static and couldn't modify any state, but remember, an interface still cannot (thankfully) contain fields, so there is no state representation that the the default implementations could call — just like in the case of static methods (it is true that they can call other interface methods, but since interface methods were always public before, you could do that with extension methods as well). So not only do they enforce but design, but they are pretty much useless as well. I strongly believe that by the time C# 8 comes out and I have to update the coding standards for some of my clients, I will have this one added to the "no-no" list.

Akos Nagy
Posted in C#