Как я могу вызвать метод по умолчанию вместо конкретной реализации

9

Почему поведение методов интерфейса по умолчанию изменилось в C # 8? В прошлом следующий код (когда по умолчанию методы интерфейса был демо не выпущен):

interface IDefaultInterfaceMethod
{
    // By default, this method will be virtual, and the virtual keyword can be here used!
    virtual void DefaultMethod()
    {
        Console.WriteLine("I am a default method in the interface!");
    }

}

interface IOverrideDefaultInterfaceMethod : IDefaultInterfaceMethod
{
    void IDefaultInterfaceMethod.DefaultMethod()
    {
        Console.WriteLine("I am an overridden default method!");
    }
}

class AnyClass : IDefaultInterfaceMethod, IOverrideDefaultInterfaceMethod
{
}

class Program
{
    static void Main()
    {
        IDefaultInterfaceMethod anyClass = new AnyClass();
        anyClass.DefaultMethod();

        IOverrideDefaultInterfaceMethod anyClassOverridden = new AnyClass();
        anyClassOverridden.DefaultMethod();
    }
}

имеет следующий вывод:

Консольный вывод:

Я метод по умолчанию в интерфейсе!
Я переопределенный метод по умолчанию!

Но с последней версией C # 8 приведенный выше код выдает следующий вывод:

Консольный вывод:

Я переопределенный метод по умолчанию!
Я переопределенный метод по умолчанию!

Кто-нибудь может объяснить мне, почему это поведение изменилось?

Замечания:

IDefaultInterfaceMethod anyClass = new AnyClass(); anyClass.DefaultMethod();

((IDefaultInterfaceMethod) anyClass).DefaultMethod(); // STILL the same problem!??
Бассам Алугили
источник
2
До C # 8 не было никаких методов интерфейса по умолчанию . Второй вывод - ожидаемый случай - когда вы реализуете метод интерфейса, вы ожидаете, что он будет вызван. Возможно, вы ссылаетесь на более старую спецификацию? Я ожидаю, что он был заброшен, потому что нарушает ожидаемое поведение метода интерфейса
Panagiotis Kanavos
3
Лучшим вопросом будет «как я могу вызвать метод по умолчанию вместо конкретной реализации?» на что ответ "вы еще не можете, потому что синтаксис base.DefaultMethod () был удален из C # 8"
Panagiotis Kanavos
4
Вот страница встречи разработчиков, где обсуждались и отбрасывались базовые вызовы для C # 8 Cut base() syntax for C# 8. We intend to bring this back in the next major release.. Это потребует поддержки во время выполнения для правильной работы.
Панагиотис Канавос
3
Интерфейс - это интерфейс всегда. Когда я реализую метод интерфейса, я ожидаю, что все клиенты будут вызывать реализованный метод. Клиенты не должны заботиться о том, какой класс реализует метод - у них есть интерфейс, и они его вызывают.
Панагиотис Канавос
2
Что касается синтаксиса, который вы опубликовали, он должен быть из действительно старого предложения - DIM могут вызываться только явно, как явно реализованные интерфейсы. Это предложение , хотя, использует явный синтаксис интерфейса для ... сделайте противоположные от virtualI догадываются? И, возможно, введение наследства алмаза
Panagiotis Kanavos

Ответы:

6

Я подозреваю, что лучший вопрос будет:

Как я могу вызвать метод по умолчанию вместо конкретной реализации?

Эта функция была запланирована, но была вырезана из C # 8 в апреле 2019 года , потому что для эффективной реализации потребуется поддержка из среды выполнения. Это не может быть добавлено вовремя перед выпуском. Эта функция должна хорошо работать как для C #, так и для VB.NET - F # в любом случае не любит интерфейсы.

если BM не присутствует во время выполнения, вызывается AM (). Для base () и интерфейсов это не поддерживается средой выполнения, поэтому вызов вместо этого вызовет исключение. Мы хотели бы добавить поддержку для этого во время выполнения, но сделать этот выпуск слишком дорого.

У нас есть некоторые обходные пути, но у них нет нужного нам поведения, и они не являются предпочтительным кодом.

Наша реализация для C # несколько работоспособна, хотя и не совсем то, что мы хотели бы, но реализация VB была бы намного сложнее. Более того, реализация для VB потребует, чтобы методы реализации интерфейса были публичной поверхностью API.

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

interface I1
{ 
    void M(int) { }
}

interface I2
{
    void M(short) { }
}

interface I3
{
    override void I1.M(int) { }
}

interface I4 : I3
{
    void M2()
    {
        base(I3).M(0) // What does this do?
    }
}
Панагиотис Канавос
источник
Я оставлю это на некоторое время, прежде чем отметить ответ. может быть, вы получите несколько голосов за вашу хорошую работу :-) спасибо!
Бассам Алугили
1
@BassamAlugili только потому, что кто-то спросил что-то подобное месяц назад. Тогда я хоть Why would you do that?. Тогда я узнал протокол встречи
Панагиотис Канавос