类似于带有定义c#的抽象的东西

Mr.*_*ome 2 c# validation virtual-functions abstract-methods

也许这首先是糟糕的设计,但我有一个抽象的基类,它有一个方法 validate

public abstract class abClass{
  string str1;
  string str2;

  public virtual bool validate(){...};
}
Run Code Online (Sandbox Code Playgroud)

我知道每一个派生类中都会有需要验证的属性,但我不希望有复制粘贴验证的str1str2每个抽象方法.

我想确保未来的开发人员(包括我自己)会记得包含并填写验证方法.从我所看到的,没有办法给出一个抽象方法定义,或强制虚拟方法被覆盖.

到目前为止,我所听到的就是"你应该让开发者选择他/她想做的事情." 这对我来说不够好,它反对制衡,以帮助你不犯错误.我不介意他们是否积极选择没有任何实现代码,但如果他们忘记了,那么稍后在未验证派生字段时会引起头疼.

对此问题的任何建议?

Tho*_*que 6

您可以使用Template方法模式:

public bool Validate()
{
    // Call base class validation
    if (!ValidateCore())
        return false;

    // Call specific validation code (overridden by derived classes)
    return ValidateOverride();
}

private bool ValidateCore()
{
    // Validate str1 and str2
    // ...
}

protected abstract bool ValidateOverride();
Run Code Online (Sandbox Code Playgroud)

这样,派生类必须覆盖ValidateOverride(因为它是抽象的),并且它们不能忘记调用ValidateCore,因为它是由基类中的非虚方法调用的.


Fed*_*gui 5

Martin Fowler在他的CallSuper文章中讨论了这个问题.

他基本上声明,在重写时要求类的子类调用基类方法是一种不好的做法或反模式:

Call Super是一种在OO框架中不时出现的轻微气味(如果你愿意,也可以是反模式).它的症状很容易发现.你继承自一个超类,以便插入一些框架.文档说的是"做自己的事情,只是继承过程方法.但重要的是要记住通过调用超类来启动你的方法"

他提出的解决方案是基类应该自己做所需的事情,同时让派生类只关心派生类的关注点:

相反,API应该记住你的家政电话.通常的方法是使handle方法成为Template Method,如下所示:

//translation of java code to proper C#
public abstract class EventHandler ...
{
    public void Handle (BankingEvent e) 
    {  
        HouseKeeping(e); //this is required by the base class.
        DoHandle(e); //Here, control is delegated to the abstract method.
    }

    protected abstract void DoHandle(BankingEvent e);
}

public class TransferEventHandler: EventHandler
{
    protected override void DoHandle(BankingEvent e) 
    {
       initiateTransfer(e);
    }
}
Run Code Online (Sandbox Code Playgroud)