Question

I have a setup similar to the following:

class A
{
    int commonField1;
    int commonField2;
    int commonField3; 
    // ...

    public A(string[] tokens, string connectionID, ContractIDMap contractIDMap, OrderStatus currentStatus /* ... */)
    {
        // Parses tokens in order to initialize the class members...
    }
}

class B : A
{
    int derivedField;

    public B(string[] differentSetOfTokens, string connectionID, ContractIDMap contractIDMap, OrderStatus currentStatus /* ... */)
    {
        // Parses differentSetOfTokens to initialize fields in class A as well as the fields in class B.
    }
}

Basically, the problem I am running into is that in the body of the derived class constructor, I need to set fields that are defined in the base class. What is the cleanest way to accomplish what I am trying to do here? I could create a default base class constructor that the derived class calls but that is obviously not a good solution. The best solution I came up with on my own was to create a static factory method in the derived class which in turn calls a new version of the base class constructor that accepts the base fields. Example:

class A
{
    int commonField1;
    int commonField2;
    int commonField3; 
    // ...

    public A(string[] tokens, string connectionID, ContractIDMap contractIDMap, OrderStatus currentStatus /* ... */)
    {
        // Parses tokens in order to initialize the class members...
    }

    public A(int commonField1, int commonField2, int commonField3)
    {
        // Set members here...
    }
}

class B : A
{
    int derivedField;

    public B(int commonField1, int commonField2, int commonField3, int derivedField)
        : base(commonField1, commonField2, commonField3)
    {
        this.derivedField = derivedField;
    } 

    static B CreateBFromDifferentSetOfTokens(string[] tokens, string connectionID, ContractIDMap contractIDMap, OrderStatus currentStatus /* ... */)
    {
        // Do parsing work here...

        return new B(commonField1, commonField2, commonField3, derivedField);
    }
}

Is there a better way to do this?

Was it helpful?

Solution

The cleanest and correct way is to delegate that responsibility to the constructor of the base class:

public B(string[] differentSetOfTokens, string connectionID, ContractIDMap contractIDMap, OrderStatus currentStatus /* ... */)
    : base(differentSetOfTokens, connectionID, ContractIDMap contractIDMap, OrderStatus currentStatus)
{
    ...

Basically, you add:

: base(...)

and pass parameters to the base constructor and let it handle setting those fields. Then, in the constructor in the derived class, you set the fields of the derived class.

Note that whether you want to or not, a constructor of the base class will be called when you call the constructor of a derived class. As such, either you will have a parameterless constructor in the base class, or you need to pass the arguments to the base constructor.

To run the parameters for the derived class through a method in order to "fix" them before passing them to the base class, make separate static methods in the derived class for each parameter, and then you can do:

: base(ReformatTokens(differentSetOfTokens), ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top