私有助手方法的继承和覆盖

时间:2014-04-09 16:23:41

标签: c# .net inheritance override

我发现了几个问题,解释了覆盖和隐藏方法的虚拟/覆盖/新关键字,但它们似乎并没有解决我的情况。我有在我的MVC控制器中进行验证的代码,如下所示:

public class AController : BaseController
{
    private bool validate()
    {
        //code for A validation

        return base.validate();
    }
}

public class BController : BaseController
{
    private bool validate()
    {
        //code for B validation

        return base.validate();
    }
}

public class BaseController : Controller
{
    protected bool validate()
    {
        //code for common validation
        return isValid;
    }
}

A和B都在他们的创建和编辑POST方法中调用this.validate()。据我所知,这工作正常,但我不明白何时/如果我应该使用虚拟/覆盖。受保护的基本方法应该是虚拟的吗?它会改变什么吗?我没有得到关于“隐藏继承的成员”的编译器警告,这是我在其他时候看到的,当我不使用“覆盖”时。我猜测虚拟/覆盖不起作用,因为validate()是一个私有方法。我知道我也可以将BaseController.validate()重命名为其他东西,比如BaseValidate(),而不必考虑覆盖。这是否重要,或者该方法被称为“验证”还是其他名称是否相同?

3 个答案:

答案 0 :(得分:1)

使用您的代码,如果BaseController中的某些方法想要验证控制器,则不能。它可以调用validate,但由于它是非虚方法,因此它只执行基类的有效性定义。您可能希望它使用实际派生类型的有效性定义,而不是省略其他检查。

由于该方法为private而没有编译器警告,正如您所猜测的那样。 private方法无法覆盖该方法;他们永远不可能是虚拟的。它必须始终隐藏同一方法的任何继承定义。

答案 1 :(得分:1)

  

我应该使用virtual / override吗?

我假设派生控制器中的其他方法调用validate()。在这种情况下,它看起来不像你需要它。

如果你想以相反的方式构建验证逻辑,你可以从覆盖中受益,基类在子类中调用可选的附加验证器。

public class AController : BaseController
{
    protected override bool additionalValidate()
    {
        //code for A validation

        return isValid;
    }
}

public class BController : BaseController
{
    protected override bool additionalValidate()
    {
        //code for B validation

        return isValid;
    }
}

public class BaseController : Controller
{
    virtual bool additionalValidate() {
        return true;
    }
    protected bool validate()
    {
        //code for common validation
        return isValid && additionalValidate();
    }
}

此模式称为Template Method。它不如你的实现脆弱,因为子类不能忘记"调用基类验证。

  

我没有收到关于"隐藏继承成员的编译器警告"我曾经在其他时候看到过我没有使用"覆盖"。

你是对的 - 这是因为子类中的bool validate()方法是private

答案 2 :(得分:0)

你可以使BaseController抽象化。

然后创建一个抽象属性,你们所有人都必须实现这些属性。

所以,你的例子将成为:

public class AController : BaseController
{
    protected override bool abstractValidation()
    {
       //code for A validation
    }
}

public class BController : BaseController
{
    protected override bool abstractValidation()
    {
       //code for B validation
    }
}

public abstract class BaseController
{
    protected abstract bool abstractValidation();

    protected bool validate()
    {
        //code for common validation

        //then, call the implementations validation method
        var isValid = abstractValidation();

        return isValid;
    }
}