Reputation: 11914
I've found several questions explaining virtual/override/new keywords for overriding and hiding methods, but they don't seem to address the situation I have. I have code for doing validation in my MVC controllers that looks like this:
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 and B both call this.validate() in their create and edit POST methods. As far as I can tell, this works fine, but I don't understand when / if I should be using virtual / override. Should the protected base method be virtual? Would it change anything if it were? I'm not getting the compiler warning about "hiding inherited member" that I've seen at other times when I don't use "override". I'm guessing that virtual / override don't come into play because validate() is a private method. I know I could also rename the BaseController.validate() to something else, such as BaseValidate(), and not have to think about overriding at all. Would that matter at all, or is it the same thing whether the method is called "Validate" or a different name?
Upvotes: 1
Views: 407
Reputation: 726589
Should I be using
virtual
/override
?
I am assuming that other methods in derived controllers call validate()
. In this situation it does not look like you need it.
You could potentially benefit from an override if you wanted to structure your validation logic the other way around, with the base class calling optional additional validators in subclasses.
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();
}
}
This pattern is called the Template Method. It is less fragile than your implementation, because subclasses cannot "forget" to call base class validation.
I'm not getting the compiler warning about "hiding inherited member" that I've seen at other times when I don't use "override".
You are correct - that is because the bool validate()
methods in the subclasses are private
.
Upvotes: 1
Reputation: 203829
With your code, if some method in BaseController
wanted to validate the controller, it couldn't. It could call validate
, but since it's a non-virtual method, it would only perform the base class's definition of validity. You probably want it to use the actual derived type's definition of validity, rather than omitting the additional checks.
There is no compiler warning due to shadowing the member because the method is private
, as you guessed. A private
method couldn't possibly override the method; they can never be virtual. It must always shadow any inherited definition of the same method.
Upvotes: 1
Reputation: 38519
You could make BaseController
abstract.
Then create an abstract property that all of you descended types must implement.
So, you example would become:
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;
}
}
Upvotes: 0