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

Перегрузка и наследование метода

У меня есть следующие классы:

public class BaseRepository
{
    public virtual void Delete(int id)
    {
        Console.WriteLine("Delete by id in BaseRepository");
    }
}

public class EFRepository: BaseRepository
{
    public override void Delete(int id)
    {
        Console.WriteLine("Delete by Id in EFRepository");
    }

    public void Delete(object entity)
    {
        Console.WriteLine("Delete by entity in EFRepository");
    }
}

Затем я использую его как:

var repository = new EFRepository();
int id = 1;
repository.Delete(id);

Почему в этом случае только EFRepository.Delete(object entity) будет вызывать?

4b9b3361

Ответ 1

В принципе, способ вызова метода работает на С# в том, что компилятор сначала смотрит на наиболее производный класс и видит, применимы ли какие-либо новые объявленные методы (не включая переопределения) для аргументов для вызова. Если есть хотя бы один применимый метод, то получается перегрузочное разрешение, которое является лучшим. Если этого не происходит, он пробует базовый класс и т.д.

Я согласен, что это удивительно - это попытка противостоять проблеме "хрупкого базового класса", но я лично предпочел бы, чтобы любые переопределенные методы были включены в набор кандидатов.

Вызов метода описан в разделе 7.6.5.1 спецификации С# 5. Здесь важны следующие компоненты:

  • Набор методов-кандидатов сводится к тому, чтобы содержать только методы из самых производных типов: для каждого метода C.F в наборе, где C - это тип, в котором объявлен метод F, все объявленные методы в базовом типе C удаляются из набора. Кроме того, если C - это тип класса, отличный от объекта, все методы, объявленные в типе интерфейса, удаляются из набора. (Это последнее правило влияет только тогда, когда группа методов была результатом поиска элемента в параметре типа, имеющем эффективный базовый класс, отличный от объекта, и непустой эффективный набор интерфейсов.)

И в части поиска элемента из 7.4 методы override явно удаляются:

Члены, которые включают модификатор override, исключаются из набора.

Ответ 2

Потому что: public override void Delete (int id) будет переопределять только метод базового класса, который: public virtual void Delete (int id).

В то время как public void Delete (объект объекта) является методом класса EFRepository, поэтому, когда вы выполняете метод из объекта EFRepository, он будет вызывать собственный метод strong > , который является не чем иным, как public void Delete (объект объекта)