Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I call the default method instead of the concrete implementation

Why is the behavior of Default Interface Methods changed in C# 8? In the past the following code (When the Default interface methods was demo not released):

interface IDefaultInterfaceMethod
{
    // By default, this method will be virtual, and the virtual keyword can be here used!
    virtual void DefaultMethod()
    {
        Console.WriteLine("I am a default method in the interface!");
    }

}

interface IOverrideDefaultInterfaceMethod : IDefaultInterfaceMethod
{
    void IDefaultInterfaceMethod.DefaultMethod()
    {
        Console.WriteLine("I am an overridden default method!");
    }
}

class AnyClass : IDefaultInterfaceMethod, IOverrideDefaultInterfaceMethod
{
}

class Program
{
    static void Main()
    {
        IDefaultInterfaceMethod anyClass = new AnyClass();
        anyClass.DefaultMethod();

        IOverrideDefaultInterfaceMethod anyClassOverridden = new AnyClass();
        anyClassOverridden.DefaultMethod();
    }
}

has the following output:

Console output:

I am a default method in the interface!
I am an overridden default method!

But with the C# 8 last version the code above is producing the following output:

Console output:

I am an overridden default method!
I am an overridden default method!

Anyone can explain to me why this behavior is changed?

Note:

IDefaultInterfaceMethod anyClass = new AnyClass(); anyClass.DefaultMethod();

((IDefaultInterfaceMethod) anyClass).DefaultMethod(); // STILL the same problem!??
like image 207
Bassam Alugili Avatar asked Jan 15 '20 09:01

Bassam Alugili


People also ask

How will you call the default method of interface without implementation?

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.

What is default method implementation?

The default methods were introduced to provide backward compatibility so that existing interfaces can use the lambda expressions without implementing the methods in the implementation class. Default methods are also known as defender methods or virtual extension methods.

What is the correct way of using default method?

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.

Do default methods need to be implemented?

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.


1 Answers

I suspect a better question would be:

How can I call the default method instead of the concrete implementation?

The feature was planned but was cut from C# 8 in April 2019, because an efficient implementation would require support from the runtime. This couldn't be added in time before release. The feature would have to work well both for C# and VB.NET - F# doesn't like interfaces anyway.

if B.M is not present at run time, A.M() will be called. For base() and interfaces, this is not supported by the runtime, so the call will throw an exception instead. We'd like to add support for this in the runtime, but it is too expensive to make this release.

We have some workarounds, but they do not have the behavior we want, and are not the preferred codegen.

Our implementation for C# is somewhat workable, although not exactly what we would like, but the VB implementation would be much more difficult. Moreover, the implementation for VB would require the interface implementation methods to be public API surface.

It will work through a base() call similar to how classes work. Coopying the proposal example :

interface I1
{ 
    void M(int) { }
}

interface I2
{
    void M(short) { }
}

interface I3
{
    override void I1.M(int) { }
}

interface I4 : I3
{
    void M2()
    {
        base(I3).M(0) // What does this do?
    }
}
like image 119
Panagiotis Kanavos Avatar answered Oct 02 '22 08:10

Panagiotis Kanavos