Как сохранить некоторые реализации методов интерфейса по умолчанию в классе реализации в C# 8.0?

Можно было бы подумать, что в C# 8.0 вы должны иметь возможность делать следующее (в соответствии с этим (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);
    ...
}

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

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

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

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

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

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

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

ОШИБКИ:

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

Отвечу на вопрос в комментариях: не уточнил LangVersion прямо в .csproj файл.

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

Проблема заключалась в ReSharper, см. /questions/51362766/kak-sohranit-nekotoryie-realizatsii-metodov-interfejsa-po-umolchaniyu-v-klasse-r/51362776#51362776

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

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

1 ответ

Решение

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

Другие вопросы по тегам