Reputation: 3435
I have the following classes:
public abstract class BusinessRule
{
public string PropertyName { get; set; }
public string ErrorMessage { get; set; }
public BusinessRule(string propertyName)
{
PropertyName = propertyName;
ErrorMessage = propertyName + " is not valid";
}
public BusinessRule(string propertyName, string errorMessage)
: this(propertyName)
{
ErrorMessage = errorMessage;
}
}
And
public class ValidateId : BusinessRule
{
public ValidateId(string propertyName) : base(propertyName)
{
ErrorMessage = propertyName + " is an invalid identifier";
}
public ValidateId(string propertyName, string errorMessage)
: base(propertyName)
{
ErrorMessage = errorMessage;
}
public override bool Validate(BusinessObject businessObject)
{
try
{
int id = int.Parse(GetPropertyValue(businessObject).ToString());
return id >= 0;
}
catch
{
return false;
}
}
}
And
public class Customer : BusinessObject
{
public Customer()
{
AddRule(new ValidateId("CustomerId"));
}
}
From within the Customer class I am adding a new business rule - ValidateId by calling it's constructor, which is fine, but then ValidateId's constructor is calling the base class constructor, this is where I start to get a little confused.
Why do I need to call the base class constructor when ValidateId constructor can do what I am trying to achieve? And both ValidateId constructor and the base constructor is setting the Error Message to something:
This is in base constructor:
PropertyName = propertyName;
ErrorMessage = propertyName + " is not valid";
and this is in ValidateId constructor:
ErrorMessage = propertyName + " is an invalid identifier";
Which one of the ErrorMessage will be used to display the error to the user?
Also if I remove the : base(propertyName)
and not call the base constructor I get BusinessRule does not contain parameterless constructor error message, obviously I can just add a parameterless constructor to the Businessrule and implement everything in ValidateId constructor but I want to know what are the advantages/implications of calling or not calling the base constructor?
Thanks
Upvotes: 1
Views: 1371
Reputation: 456
Just create BusinessRule() constructor without paramters. Call base() in validateId()
Upvotes: 0
Reputation: 1499860
Why do I need to call the base class constructor when ValidateId constructor can do what I am trying to achieve?
You always have to go through a constructor at every level of the inheritance hierarchy - as otherwise any "skipped" levels wouldn't have a chance to initialize themselves and validate the parameters public ValidateId(string propertyName) : base(propertyName) { ErrorMessage = propertyName + " is an invalid identifier"; }.
Imagine if you could create a class deriving from FileStream
which could skip the existing FileStream
constructors - what file would that represent? Where would it get its data from?
It seems to me that ValidateId(string propertyName)
should be implemented as:
public ValidateId(string propertyName)
: base(propertyName, propertyName + " is an invalid identifier")
{
}
Only one piece of code needs to be setting the error message - and personally I'd actually make the setters private within BusinessRule
, or even use a separate readonly field and only provide a getter at all.
Upvotes: 5