Это ключевое слово существует? Когда переопределяющий метод должен вызвать родительский - PullRequest
6 голосов
/ 20 мая 2010

Часто в документации C # вы встречаете члена, в описании которого говорится что-то вроде «обязательно вызовите базовый метод, если вы переопределите это».

Есть ли способ убедиться, что во время компиляции фактически вызвана базовая функция?

Вот пример: Реализация метода утилизации

С первых строк:

Метод Dispose типа должен освобождать все ресурсы, которыми он владеет. Это следует также освободить все ресурсы принадлежит его базовым типам, вызывая его метод Dispose родительского типа.

EDIT

Я просматривал и наткнулся на эту статью, которая кажется довольно актуальной. Это скорее мелочь, чем ошибка, т.е. он имеет допустимое использование (например, упомянутое):

Вызов Super

Ответы [ 3 ]

8 голосов
/ 20 мая 2010

Вы не можете применить это, но вы можете сделать это с помощью вызова, подобного base.Foo(bar). base позволяет получить доступ к членам класса, от которого вы наследуете.

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

abstract class Animal
{
    public virtual void Speak()
    {
        Console.WriteLine("I'm an animal.");
    }
}

class Dog : Animal
{
    public override void Speak()
    {
        base.Speak();
        Console.WriteLine("I'm a dog.");
    }
}

Проблема здесь в том, что любой класс, унаследованный от Animal, должен вызывать base.Speak();, чтобы обеспечить выполнение базового поведения. Вы можете автоматически применить это, используя следующий (немного другой) подход:

abstract class Animal
{
    public void Speak()
    {
        Console.WriteLine("I'm an animal.");
        DoSpeak();
    }

    protected abstract void DoSpeak();
}

class Dog : Animal
{
    protected override void DoSpeak()
    {
        Console.WriteLine("I'm a dog.");
    }
}

В этом случае клиенты по-прежнему видят только полиморфный метод Speak, но поведение Animal.Speak гарантированно будет выполнено. Проблема в том, что если у вас есть дополнительное наследование (например, class Dachsund : Dog), вам нужно создать еще один абстрактный метод, если вы хотите, чтобы гарантированно выполнялось Dog.Speak.

5 голосов
/ 20 мая 2010

Вы можете назвать это так:

public override void MyFunction()
{
    // do dome stuff
    SomeStuff();

   // call the base implementation
   base.MyFunction();
}

Но если вы спрашиваете, можно ли это "проверить" во время компиляции - нет.

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

0 голосов
/ 20 мая 2010

Обычным шаблоном для одного уровня наследования является предоставление не виртуального метода шаблона с виртуальной точкой расширения.

protected virtual void ExtensionPoint () { }

public void TemplateMethod () {
    ExtensionPoint();
    ThisWillAlwaysGetCalled();
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...