Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default implementation in interface is not seen by the compiler?

Here is a my code inside a c# project that targets .NET Core 3.0 (so I should be in C# 8.0) with Visual Studio 2019 (16.3.9)

public interface IJsonAble
{
    public string ToJson() => System.Text.Json.JsonSerializer.Serialize(this);
}

public class SumRequest : IJsonAble
{
    public int X { get; set; }

    public int Y { get; set; }

    public void Tmp()
    {
        new SumRequest().ToJson(); //compile error
    }
}

The compile error is:

CS1061 'SumRequest' does not contain a definition for 'ToJson' and no accessible extension method 'ToJson' accepting a first argument of type 'SumRequest' could be found (are you missing a using directive or an assembly reference?)

Can someone shed some light on this behavior ?

like image 671
Christophe Blin Avatar asked Nov 20 '19 09:11

Christophe Blin


People also ask

Can we have default implementations in the interface?

Interfaces can have default methods with implementation in Java 8 on later. Interfaces can have static methods as well, similar to static methods in classes. Default methods were introduced to provide backward compatibility for old interfaces so that they can have new methods without affecting existing code.

What is default implementation of interface in Java?

The Java Tutorials Documentation defines default interface methods: Default methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces. and then proceeds to supply a convoluted, 50+ line example.

Can an interface have a default implementation C#?

An interface in C# can only implement abstract methods, methods that are defined but not implemented. However, in C# 8.0 onward, interfaces can provide an implementation for the method defined in them, which is known as the default implementation.


2 Answers

Methods are only available on the interface, not the class. So you can do this instead:

IJsonAble request = new SumRequest()
var result = request.ToJson();

Or:

((IJsonAble)new SumRequest()).ToJson();

The reason for this is it allows you to add to the interface without worrying about the downstream consequences. For example, the ToJson method may already exist in the SumRequest class, which would you expect to be called?

like image 164
DavidG Avatar answered Oct 28 '22 23:10

DavidG


Try using (new SumRequest() as IJsonAble).ToJson(); to help the compiler a bit.

Anyway, I'm sure what you're after is (this as IJsonAble).ToJson(), assuming you want to apply ToJson on current SumRequest instance.

like image 40
Cosmin Sontu Avatar answered Oct 29 '22 00:10

Cosmin Sontu