سؤال

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

هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

Just create BusinessRule() constructor without paramters. Call base() in validateId()

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top