代码之家  ›  专栏  ›  技术社区  ›  Carlos

这个关键字存在吗?当重写方法需要调用父级时

  •  6
  • Carlos  · 技术社区  · 16 年前

    通常,在C文档中,您会遇到一个成员,其中描述中会沿着“如果您重写了它,请确保调用基方法”这一行说明一些内容。

    有没有一种方法可以确保在编译时实际上调用了基函数?

    下面是一个例子: Implementing a Dispose Method

    从第一行开始:

    类型的Dispose方法应释放 它拥有的所有资源。它 还应释放所有资源 通过调用它的 父类型的Dispose方法。

    编辑

    我在浏览,我看到了这篇文章,它似乎很相关。它比一个错误要小得多,即它有有效的用途(如前面提到的那些用途):

    Call Super

    3 回复  |  直到 16 年前
        1
  •  8
  •   Chris Schmich    16 年前

    你不能强制执行,但你可以通过一个类似 base.Foo(bar) . base 允许您访问从中继承的类的成员。

    您可以通过使用 template method pattern . 例如,假设您有以下代码:

    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 保证执行。

        2
  •  5
  •   Rob Levine    16 年前

    你可以这样称呼它:

    public override void MyFunction()
    {
        // do dome stuff
        SomeStuff();
    
       // call the base implementation
       base.MyFunction();
    }
    

    但如果你问它是否可以在编译时被“检查”——不。

    您可以使用依赖性分析工具(如ndepend)创建规则来检查是否正在执行,并将规则作为编译的一部分运行,但我认为您不能从编译器本身执行。

        3
  •  0
  •   Pete Kirkham    16 年前

    单一继承级别的一个常见模式是提供具有虚拟扩展点的非虚拟模板方法。

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

    如果对操作的所有调用都调用模板方法,则将调用扩展点的任何重写,以及模板方法中始终被调用的代码。

    推荐文章