Подтвердить что ты не робот

Почему базовому классу на С# разрешено реализовать контракт на интерфейс, не наследуя от него?

Я наткнулся на эту "функцию" С# - базовый класс, который реализует методы интерфейса, не должен вытекать из него.

Пример:

public interface IContract
{
    void Func();
}

// Note that Base does **not** derive from IContract
public abstract class Base
{
    public void Func()
    {
        Console.WriteLine("Base.Func");
    }
}

// Note that Derived does *not* provide implementation for IContract
public class Derived : Base, IContract
{
}

Что происходит, так это то, что Derived волшебным образом набирает открытый метод Base.Func и решает, что он реализует IContract.Func.

В чем причина этой магии?

ИМХО: эта функция "квази-реализации" очень неинтуитивная и делает проверку кода намного сложнее. Как вы думаете?

4b9b3361

Ответ 1

Причина в том, что ваш комментарий просто неверен:

//Обратите внимание, что Derived не обеспечивает реализацию для IContract

Конечно. Следуйте логике.

  • Производный должен предоставить публичный член, соответствующий каждому члену IContract.
  • Все наследуемые члены базового класса также являются членами производного класса; что определение наследования.
  • Поэтому Derived обеспечивает реализацию для IContract; его унаследованный член является членом, который выполняет требование
  • Поэтому нет ошибок.

эта функция очень неинтуитивна и делает проверку кода намного сложнее. Как вы думаете?

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

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

Кроме того, это относительно простой, простой случай. Если вы действительно хотите жаловаться на запутывание семантики интерфейса в С#, я бы потратил свое время на жалобу на семантику переопределения интерфейса. Это тот, который действительно, кажется, испекает народную лапшу. Мне всегда нужно искать эту вещь в спецификации, чтобы убедиться, что я правильно понимаю семантику.

Ответ 2

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