Как сохранить некоторые реализации метода интерфейса по умолчанию в классе реализации в C # 8.0? - PullRequest
0 голосов
/ 26 октября 2019

Можно подумать, что в C # 8.0 вы сможете сделать следующее (согласно this (1-й фрагмент) ):

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 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);
    ...
}

Нет, похоже,этот метод является рекурсивным (несмотря на upcast) и вызовет наше любимое Stack Overflow исключение.

Так что мой вопрос (абстрагируясь от того факта, что я мог изменить дизайн в моем примере), есть ли способсохранить реализацию для конкретного метода по умолчанию, желательно без необходимости прибегать к хакерским или статическим методам расширения хелперов? Я мог бы вызвать метод статического расширения как в интерфейсе, так и в классе, но это как бы отрицательно сказывается на назначении этой функции.

// EDIT

Я должен признать, что это смущает меня, и кажется, что я пропускаючто-то критическое, что очевидно для других людей. Я не предоставил дополнительную информацию, потому что не считал свою проблему специфичной для кода. Давайте посмотрим на этот простой пример (взят с сайта, на который я ссылался в начале моего сообщения):

enter image description here

Согласно комментарию @Panagiotis Kanavos: No, default members don't need to be implemented (...) то, что я сделал скриншот, не должно быть правдой. Можешь, пожалуйста, просветить меня?

// РЕДАКТИРОВАТЬ 2

Как видите, я правильно нацеливаюсь .NET CORE 3.0 с C# 8.0.

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

ОШИБКИ:

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

Чтобы ответить на вопрос в комментариях: я не указал LangVersion явно в файле .csproj.

// РЕДАКТИРОВАТЬ 3

проблема была в ReSharper, см .: https://stackoverflow.com/a/58614702/3783852

Мой комментарий был удален, предположительно владельцем ответа, поэтому я напишу его здесь: подсказка заключалась в том, что на самом деле не было номеров ошибок, нокомпиляция была заблокирована. Оказалось, что есть возможность заблокировать компиляцию, когда эти ошибки возникают в ReSharper.

Кажется, что в конце концов это возможный дубликат, но прийти к такому выводу было довольно странно:).

1 Ответ

0 голосов
/ 29 октября 2019

Проблема вызвана ReSharper, ссылка:
https://youtrack.jetbrains.com/issue/RSRP-474628
Похоже, что проблема будет решена в версии v2019.3, и в настоящее время у нас есть v2019.2.3. Вы можете настроить ReSharper, чтобы блокировать компиляцию в зависимости от серьезности проблемы; временное решение заключается в том, чтобы временно отключить эту функцию.

...