【问题标题】:Is it possible to skip overriden methods code when based on base code基于基本代码时是否可以跳过覆盖的方法代码
【发布时间】:2014-11-18 10:57:09
【问题描述】:

我有一个快速的 C# 问题。 如果我有这样的方法

    protected virtual void Delete(Guid? guidId)
    {
    }

然后我像这样覆盖它

    protected override void Delete(Guid? id)
    {
        if (id != null)
        {
          code goes here 
        }
    }

我可以像这样将 if 语句放在基本方法中

    protected virtual void Delete(Guid? guidId)
    { 
        if (id != null)
        {
          code goes here 
        }
    }

然后这样称呼它

    protected override void Delete(Guid? id)
    {
      base.Delete(id);
      code goes here  
    }

但是现在在被覆盖的方法中,如果基方法没有进入那个 if 语句,我不想​​继续。 我只是想知道这是否可能。谢谢你:)

【问题讨论】:

  • 让方法返回 bool 是一种简单的解决方法。
  • 为什么不在派生类中重新检查这个条件?
  • @HimBromBeere 因为 id 决不能为空,并且通过调用 base 来检查这一点,我的带有大量嵌套 if 的大型删除方法将减少一个缩进。

标签: c# overriding virtual


【解决方案1】:

您似乎正在寻找Template Method pattern,通常也称为挂钩方法

public class Base 
{
    protected void Delete(Guid? id)
    { 
        if (id != null)
        {
           //code goes here

           //execute hook only if id is not null
           OnDelete(id);
        }
    }

    protected virtual void OnDelete(Guid? guid) {}
}


public class Derived : Base
{
    protected override void OnDelete(Guid? guid)
    {
        //code goes here
    }
}

如果你想强制所有的基类都实现这个钩子,就让方法抽象。 否则,如果实现钩子是可选的,则将其定义为空方法,就像我在上面所做的那样。

这种模式采用了一个非常强大的原则:Hollywood principle不要给我们打电话,我们会打电话给你的!派生类不会像你的例子那样调用基类——相反,基类会调用派生类if 合适。

【讨论】:

  • 您好,谢谢您的回复,它看起来很有趣,但我不太明白它是如何工作的。因为覆盖 void OnDelete 不会在任何时候从基础调用 Delete 以查看该 id 是否不为空。你能扩展一下吗?我想知道我在 ovveride OnDelete 内部做什么,以确保完成“如果”检查。如果 guid 为空,我希望 protected override void OnDelete(Guid?guid) { } this 跳出该方法,而不是如果我在其中调用 Delete ,无论如何它都会转到下一行。希望这是有道理的。
  • @adminSoftDK 基类上的Delete 方法为您进行检查。 OnDelete 方法只会在 id 不为 null 时被调用,因此您可以将业务逻辑转储到 OnDelete 覆盖中,而不必担心检查 id。对于像您这样的场景,这是一个非常好的模式,并且 WPF、WinForms、WinRT 等框架在所有地方都使用它(例如,OnPageLoaded 钩子)。
  • 另外,您现在可以将Delete 设为私有方法。基类不需要调用它。
  • 它看起来像一个很棒的模式(我从未听说过),因为我在各处(在 WPF 中)检查类似的空值。但是我仍然看不到是什么告诉(调用)要执行的 Delete 方法。我想我只需要从您提供的链接开始阅读此模式:)
  • @adminSoftDK 在您的原始代码中,是谁调用了Delete 方法?
【解决方案2】:

更改方法以返回bool 以指示是否采用分支,例如:

class Base
{
    protected virtual bool Delete(Guid? id)
    {
        bool result = false;

        if (id != null)
        {
            // ...

            result = true;
        }

        return result;
    }
}

internal class Derived : Base
{
    protected override bool Delete(Guid? id)
    {
        if (!base.Delete(id))
            return false;

        // ...

        return true;
    }
}

【讨论】:

  • 感谢您的快速回复。我很感激,我决定坚持 if(id != null) 因为在我的情况下不需要返回任何东西。但是我从这篇文章中学到了一些有趣的小方法:) Rgs
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-07
  • 1970-01-01
相关资源
最近更新 更多