Christophe Blin
Christophe Blin

Reputation: 1909

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 ?

Upvotes: 27

Views: 6402

Answers (2)

AxelSeven
AxelSeven

Reputation: 61

a bit of a necro but if you want to implicitly call the default method implementation without HAVING to implement it manually, you can make an extension method for the Interface itself:

public static class JsonAbleExtensions {
    public static string ToJson(this IJsonAble jsonAble)
    {
        return jsonAble.ToJson();
    }
}

This avoids using explicit runtime casting or forcing users of the interface to implement the method manually on all classes that inherit from it.

Upvotes: 6

DavidG
DavidG

Reputation: 118937

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?

Upvotes: 30

Related Questions