Это ключевое слово существует? Когда метод переопределения должен назвать родителя

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

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

Вот пример: Реализация Расположить Метода

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

Тип Располагает метод, должен высвободить все средства, которыми он владеет. Это должно также высвободить все средства, принадлежавшие его базовым типам путем вызова его родительского типа, Располагают метод.

Править

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

Звоните супер

6
задан Carlos 20 May 2010 в 14:04
поделиться

3 ответа

Вы не можете сделать это принудительно, но вы можете сделать это через вызов типа 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 гарантированно выполнялся.

8
ответ дан 8 December 2019 в 18:33
поделиться

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

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

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

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

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

5
ответ дан 8 December 2019 в 18:33
поделиться

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

protected virtual void ExtensionPoint () { }

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

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

0
ответ дан 8 December 2019 в 18:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: