How to retain some of the interface methods' default implementations in the implementing class in C# 8.0?

158 Views Asked by At

One would think that in C# 8.0 you should be able to do the following (according to this (1st snippet)):

public interface IRestApiClient : IRestClient
{
    ...
    Task<T> PostPrivateAsync<T>(string action, OrderedDictionary<string, object> parameters = null, DeserializeCustom<T> deserializer = null)
    {
        return QueryPrivateAsync(Method.POST, action, parameters, deserializer);
    }
    ...
}

public class SpecificClient : ExchangeClient, IRestApiClient, IRestHtmlClient, ISeleniumClient, IWebSocketClient
{

}

The example above won't compile because the interface members need to be explicitly and wholly implemented (including the methods supplying the default logic)

So one would think that the following should work:

public interface IRestApiClient : IRestClient
{
    ...
    Task<T> PostPrivateAsync<T>(string action, OrderedDictionary<string, object> parameters = null, DeserializeCustom<T> deserializer = null)
    {
        return QueryPrivateAsync(Method.POST, action, parameters, deserializer);
    }
    ...
}

public class SpecificClient : ExchangeClient, IRestApiClient, IRestHtmlClient, ISeleniumClient, IWebSocketClient
{
    ...
    public async Task<T> PostPrivateAsync<T>(string action, OrderedDictionary<string, object> parameters = null, DeserializeCustom<T> deserializer = null) 
        => await ((IRestApiClient) this).PostPrivateAsync(action, parameters, deserializer);
    ...
}

Nope, it looks like this method is recursive (despite the upcast) and will cause our favorite Stack Overflow exception.

So my question is (abstracting from the fact that I could change the design in my example), is there a way of keeping the implementation for a specific method default, preferably without the necessity of resorting to hacky or Static Helper Extension methods? I could call static extension method in both interface and the class but it kind of defeats the purpose of this feature.

// EDIT

I must admit it confuses me and it appears I am missing something critical that is obvious to other people. I didn't provide additional info because I didn't consider my issue to be code specific. Lets look at this simple example (taken from the website I linked on the beginning of my post):

enter image description here

According to @Panagiotis Kanavos comment: No, default members don't need to be implemented (...) what I screenshoted should not be true. Can sb please enlighten me?

// EDIT 2

As you can see I am properly targeting .NET CORE 3.0 with C# 8.0.

enter image description here enter image description here enter image description here enter image description here

ERRORS:

Interface method cannot declare a body
Interface member 'void CryptoBotCoreMVC.IDefaultInterfaceMethod.DefaultMethod()' is not implemented

To answer the question in the comments: I didn't specify LangVersion explicitly in the .csproj file.

// EDIT 3

The issue was ReSharper, see: https://stackoverflow.com/a/58614702/3783852

My comment have been deleted, presumably by the owner of the answer so I'll write it here: the clue was the fact that there was actually no error numbers, but the compilation was blocked. It turned out that there is an option to block compilation when these errors occur in ReSharper.

It seems that in the end this is a possible duplicate, but getting to this conclusion was quite a journey :).

1

There are 1 best solutions below

0
On BEST ANSWER

The issue is caused by ReSharper, reference:
https://youtrack.jetbrains.com/issue/RSRP-474628
It appears that the problem will be resolved in version v2019.3 and we currently have v2019.2.3. You can setup ReSharper to block compilation depending on issue severity, the workaround is to disable this feature for the time being.