我发现了几个问题,解释了覆盖和隐藏方法的虚拟/覆盖/新关键字,但它们似乎并没有解决我的情况。我有在我的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(),而不必考虑覆盖。这是否重要,或者该方法被称为“验证”还是其他名称是否相同?
答案 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;
}
}