1

I have an abstract class called ReportFunction. It has a default constructor that should always invokes the method ValidateAndSetParameters() after it is constructed.

Here is my abstract class

public abstract class ReportFunction
{

    public IList<IReportFilter> Parameters { protected get; set; }
    public ICollection<IReportFilter> ValidParameter { get; protected set; }

    /****
     * 
     * This method should validate parameters if any exists.
     * Then it should add valid parameters to the 'ValidParameter' list
     * 
     */
    public virtual void ValidateAndSetParameters()
    {
        this.ValidParameter = new Collection<IReportFilter>();
    }

    .... I removed irrelevant methods for the sake of simplicity

    public ReportFunction()
    {
        this.ValidateAndSetParameters();
    }

}

I completed ReportFunction class with the following Replace class

public class Replace : ReportFunction
{
    public override void ValidateAndSetParameters()
    {
        if (this.Parameters != null && this.Parameters.Count() == 3)
        {
            foreach (var parameter in this.Parameters)
            {
                if (parameter.ReportColumn == null)
                {
                    //Since this is a string function, the filter values should be text, force the filter type to SqlDbType.NVarChar which is the max allowed characters to replace using Replace function 
                    parameter.Type = SqlDbType.NVarChar;
                }
                this.ValidParameter.Add(parameter);
            }
        }
    }

    public Replace() :base()
    {
    }

    public Replace(IReportFilter stringExpression, string stringPattern, string stringReplacement)
    {
        this.Parameters = new List<IReportFilter>
        {
            stringExpression, 
            new ReportFilter(stringPattern),
            new ReportFilter(stringReplacement)
        };

        this.ValidateAndSetParameters();
    }

}

I initialize the Replace class one in two ways

new Replace
{
    Parameters = new List<IReportFilter>
    {
        new ReportFilter("something to search in"),
        new ReportFilter("something to search for"),
        new ReportFilter("Something to replace with"),
    }
};

or like this

Replace(new ReportFilter("something to search in"), "something to search for", "Something to replace with");

I expect or need to call the method ValidateAndSetParameters() after the class is constructed and the Parameters property is set. But what seems to be happening is that the ValidateAndSetParameters() is called before the initialization. Or for some reason Parameters is not getting set during initialization.

How can I ensure that the method ValidateAndSetParameters() is called after the class is constructed and the Parameters property is set first?

Jaylen
  • 39,043
  • 40
  • 128
  • 221

1 Answers1

2

Your second variant should work in general even though virtual method will be called two times first before ctor and then from inside ctor.

var replace= new Replace(new ReportFilter("something to search in"), "something to search for", "Something to replace with");

Why is it called two times ? Do not call overridable methods in constructors

so instead of overriding that method you can use local method or just put validation in ctor and remove overriden ValidateAndSetParameters

vlscanner
  • 448
  • 5
  • 16