Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should we use default interface method in C#?

In C# 8 and later, we have default interface methods, so:

Doesn't it ruin the principle of interface?

When should we use default interface methods instead of base (abstract) class?

like image 869
Hassan Monjezi Avatar asked Jul 10 '20 11:07

Hassan Monjezi


People also ask

Why do we need default method in interface?

Default methods enable you to add new functionality to existing interfaces and ensure binary compatibility with code written for older versions of those interfaces. In particular, default methods enable you to add methods that accept lambda expressions as parameters to existing interfaces.

When should you create an interface?

Consider using interfaces if any of these statements apply to your situation: You want to specify the behavior of a particular data type, but not concerned about who implements its behavior. You want to take advantage of multiple inheritances. You expect that unrelated classes would implement your interface.

Is default methods in an interface should have method body?

The default methods are introduced in an interface since Java8. Unlike other abstract methods these are the methods can have a default implementation. If you have default method in an interface, it is not mandatory to override (provide body) it in the classes that are already implementing this interface.

Can we call default method of interface?

A class can override a default interface method and call the original method by using super , keeping it nicely in line with calling a super method from an extended class. But there is one catch, you need to put the name of the interface before calling super this is necessary even if only one interface is added.


2 Answers

Why do we have interfaces?

From a theoretical point of view, both interface implementation and class inheritance solve the same problem: They allow you to define a subtype relationship between types.

So why do we have both in C#? Why do we need interfaces at all? Can't we just define an interface as an abstract class, just as we do, for example, in C++?

The reason for this is the diamond problem: (Image source)

enter image description here

If both B and C implement A.DoSomething() differently, which implementation should D inherit? That's a hard problem, and the Java as well as the C# designers decided to avoid it by allowing multiple inheritance only for special base types which do not include any implementation. They decided to call these special base types interfaces.

So, there is no "principle of interface". Interfaces are just a "tool" to solve a particular problem.

So why do we need default implementations?

Backwards compatibility. You wrote a vastly successful library used by thousands of developers worldwide. Your library contains some interface I, and now you decide that you need an extra method M on it. The problem is:

  • You can't add another method M to I, because that would break existing classes implementing I (because they don't implement M), and
  • you can't change I to an abstract base class, because that, as well, would break existing classes implementing I, and you will lose the ability to do multiple inheritance.

So how do default implementations avoid the diamond problem?

By not inheriting those default methods (example inspired by the one in this article, see the full article for some interesting corner cases):

interface I1
{
    void M() { Console.WriteLine("I1.M"); } // default method
}

interface I2
{
    void M() { Console.WriteLine("I2.M"); } // default method
}

class C : I1, I2 { }

class Program
{
    static void Main(string[] args)
    {
        // c, i1 and i2 reference the same object
        C c = new C();
        I1 i1 = c;
        I2 i2 = c;

        i1.M(); // prints "I1.M"
        i2.M(); // prints "I2.M"
        c.M();  // compile error: class 'C' does not contain a member 'M'
    }
}
like image 107
Heinzi Avatar answered Sep 23 '22 05:09

Heinzi


As it is explained in the documentation, there are two primary applications:

Extending existing APIs

Virtual extension 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.

It is thus intended as a means to extend APIs (= a set of interfaces) without having to update all existing implementations (since they need to implement the newly added functions).

The traits pattern

The traits pattern allows to extend a class with multiple sets of pre-implemented methods. This is not possible with abstract classes: A given class can only inherit from a single parent class, but from multiple interfaces.

Note that this feature comes with the diamond inheritance problem. Thus, apart from these specific applications, this feature should not be used to replace abstract classes.

like image 24
janw Avatar answered Sep 19 '22 05:09

janw