如何强制派生方法遵循某种模式?

时间:2014-02-07 07:26:16

标签: c#

假设我的基类中有这个方法。

public virtual void Close ()
{
    if (!IsOpen) return;

    Dispose();
    RaiseClosed();
}

我希望子类可以自由地修改方法,但要确保它先调用Dispose(),然后调用RaiseClosed()。他们可以在两者之前,之后或之间做任何事情。

如何强制子类在某个时刻调用Dispose()RaiseClosed()

编辑:我想我没有很好地澄清这个问题。派生方法可以在Dispose()之前/之后,RaiseClosed()之前/之后执行某些操作。因此,确保它在订单中调用Dispose()RaiseClosed()是不够的,因为派生的方法可以在两者之间,甚至在RaiseClosed()之后执行某些操作。

3 个答案:

答案 0 :(得分:11)

一种方法是简单地不使Close成为virtual方法。而是有另一种方法,专门设计为覆盖并从您的Close方法调用它本身正确执行您想要的变体

public void Close() { 
  if (!IsOpen) return;

  try { 
    CloseCore();
  }
  finally { 
    Dispose();
    RaiseClosed();
  }
}

protected virtual void CloseCore()
{
  // Derived types override this to customize their close
  // behavior 
}

答案 1 :(得分:1)

首先按以下方式将方法声明为非虚拟:

public void Close ()
{
    if (!IsOpen) return;

    DoClosingStuff();

    Dispose();
    RaiseClosed();
}

然后使方法DoClosingStuff()

成为虚拟
public virtual void DoClosingStuff()
{
}

答案 2 :(得分:0)

没有办法,你所能执行的只是声明。正如Jared建议的那样,您可以提供可在预测帧中执行的方法模板。另一种可以避免这种情况的方法是使用事件,但基本上模式是相同的。您只需提供钩子即可将代码添加到...

public event Action BeforeDispose;
public event Action AfterDispose;

public virtual void Close ()
{    
    if (BeforeDispose != null) BeforeDispose.Invoke();
    Dispose();
    if (AfterDispose != null) AfterDispose.Invoke();
    RaiseClosed();
}

通过这种方式,您可以限制可在模板中执行的委托类型的类型,子类可以处理这些事件或只是忽略它们。虽然,我不认为这种方法比Jared更有优势......