Вызов метода скрытого интерфейса - PullRequest
1 голос
/ 21 апреля 2020

Я пытаюсь использовать новые C# методы интерфейса по умолчанию. Может кто-нибудь объяснить следующий код и почему это происходит?

Пример минимального теста:

public static void Main()
{
    Class c = new Class();
    IInterface i = new Class();
    c.M1();
    i.M1();
    (i as IInterface).M1();
    Class2 c2 = new Class2();
    Class2Base c2b = new Class2();
    c2.M2();
    c2b.M2();
    (c2 as Class2Base).M2();
}

public interface IInterface
{
    public void M1() => Console.WriteLine("Call from interface");
}

public class Class : IInterface
{
    public void M1() => Console.WriteLine("Call from class");
}

public class Class2 : Class2Base
{
    public void M2() => Console.WriteLine("Call from class2");
}

public class Class2Base
{
    public void M2() => Console.WriteLine("Call from class2base");
}

Выходы:

Call from class
Call from class
Call from class
Call from class2
Call from class2base
Call from class2base

Я ожидаю увидеть «Вызов с интерфейса» во втором вызове аналогично использованию обычного наследования, как во втором примере.

Подводя итог:

Почему метод интерфейса скрыт и (возможно), как я все еще могу его назвать.

Кроме того, это мой первый вопрос здесь, так что любые советы добро пожаловать

1 Ответ

3 голосов
/ 21 апреля 2020

Почему скрыт метод интерфейса?

Методы интерфейса по умолчанию - именно это. Метод в интерфейсе является реализацией по умолчанию, если не предоставлена ​​другая реализация .

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

Когда вы предоставляете реализацию не по умолчанию, мы предполагаем, что новая реализация на лучше , чем реализация по умолчанию; если бы это было не лучше, вы бы не предоставили это , верно? Вы не сделали бы работу без причины, и, вероятно, вы хотите, чтобы ваша работа использовалась. Для среды выполнения было бы глупо sh вызывать реализацию по умолчанию, когда существует лучшая реализация.

Как я все еще могу это назвать?

В вашем коде ты не

Если вы хотите всегда иметь реализацию по умолчанию, которую вы можете вызвать, вы можете сделать что-то вроде:

public interface IInterface
{
    public void M1() => MyHelperMethods.M1(this);
}

public static class MyHelperMethods
{
    public static void M1(IInterface i) => 
      Console.WriteLine("Call from static");
}

А теперь, если вы хотите вызвать реализацию по умолчанию, вы можете позвонить MyHelperMethods.M1 напрямую.

...