【问题标题】:C# return from base methodC# 从基方法返回
【发布时间】:2020-11-28 05:57:52
【问题描述】:

base.OnAllyTurnStart(); 之后的代码即使基本方法返回也会继续执行。如何防止执行基本方法以下的代码?

// BASE METHOD
public virtual void OnAllyTurnStart()
{
    if(// if it is not my turn)
    return;
}


public override void OnAllyTurnStart()
{
    base.OnAllyTurnStart();

    // Code bellow should execute only when it's my turn
    // ..................................
}

【问题讨论】:

  • 如果你不希望该方法中的其他代码运行,那为什么该方法中还有其他代码?
  • @itsme86:我猜代码有时应该运行,但基本实现有早期返回逻辑,应该跳过所有后续处理。
  • 好吧,基本方法要么必须设置某种被覆盖方法可以引用的标志,要么开始返回一个可以被覆盖方法检查的值。
  • 您只是从基础返回,而不是覆盖的实现。实际上,我建议您彻底重新考虑您的系统。如果你正在寻找一个草率和讨厌的修复,你总是可以将一个 bool 包装到一个类中,然后将该类作为参数传递给 OnAllyTurnStart()。然后,您可以将类中的 bool 设为 false,并在覆盖的 if 语句中使用它来查看逻辑是否应该继续。

标签: c# return overriding virtual base


【解决方案1】:

您必须提供从被调用函数提前返回给调用者的指示。

您可以使用返回值、out 参数或参数对象上的成员(查看CancelEventArgs)。然后派生类可以检查基实现提供的指示,并知道它是否应该继续处理。

或者你可以抛出一个被事件源捕获的异常。异常有效地提供了遍历调用堆栈多个帧的长跳转。

【讨论】:

    【解决方案2】:

    这种行为的原因是您的覆盖方法没有显式返回。这与调用任何方法而不返回的行为相同。从控制流的角度来看,base.OnAllyTurnStart();Console.WriteLine("foo"); 在功能上没有区别。

    我想你想这样做是有条件的。如果函数返回一个值,你可以级联返回值:

    public override int OnAllyTurnStart()
    {
        // do other work
        return base.OnAllyTurnStart();
    }
    

    或者,您可以在调用 base.OnAllyTurnStart 后提前返回,前提是您希望某个逻辑分支有时执行其他操作:

    public override voic OnAllyTurnStart()
    {
        base.OnAllyTurnStart();
        return;
    }
    

    这可能只有在有条件逻辑来做额外工作时才有意义。如果您的方法仅执行上述操作,则您不能简单地覆盖虚拟成员,并且子类的实例在调用时将使用基类的虚拟方法。

    【讨论】:

    • 你是对的。为了简化代码,我没有包含条件逻辑。我编辑了我的帖子以包含该逻辑。想到的一个解决方案是将条件逻辑移动到覆盖内。该解决方案的问题是我必须将它包含在方法的每个覆盖中,我认为这不是一个很好的编码实践,因为当我在 10 个不同的派生类中覆盖该方法时,我基本上有相同的代码 10次。
    猜你喜欢
    • 2012-06-02
    • 2016-03-06
    • 1970-01-01
    • 2019-07-20
    • 1970-01-01
    • 1970-01-01
    • 2018-03-20
    • 1970-01-01
    • 2013-07-04
    相关资源
    最近更新 更多