私有助手方法的继承和重写
本文关键字:继承 重写 方法 | 更新日期: 2023-09-27 17:57:33
我发现了几个问题,解释了用于覆盖和隐藏方法的virtual/override/new关键字,但它们似乎无法解决我遇到的情况。我有在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(),而不必考虑重写。这有关系吗?或者该方法被称为"Validate"还是不同的名称是一样的吗?
使用您的代码,如果BaseController
中的某个方法想要验证控制器,它就无法验证。它可以调用validate
,但由于它是一个非虚拟方法,它将只执行基类的有效性定义。您可能希望它使用实际派生类型的有效性定义,而不是省略额外的检查。
正如您所猜测的,由于方法是private
,因此不会出现由于遮蔽成员而导致的编译器警告。private
方法不可能覆盖该方法;它们永远不可能是虚拟的。它必须始终覆盖同一方法的任何继承定义。
我应该使用
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();
}
}
此模式称为模板方法。它不像您的实现那样脆弱,因为子类不能"忘记"调用基类验证。
当我不使用"覆盖"时,我不会收到编译器关于"隐藏继承成员"的警告。
您是正确的,这是因为子类中的bool validate()
方法是private
。
您可以使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;
}
}