Spook
Spook

Reputation: 25927

How to keep field readonly?

Let's suppose, that we have the following class:

class C
{
    private readonly DataType data;
    private readonly AdditionalType additional;

    C(DataType newData)
    {
        data = newData;
        // LONG code evaluating additional
    }

    C(OtherType newData)
    {
        // eval data from newData
        // the same LONG code evaluating additional
    }
}

Both data and additional remain unchanged through the whole life of C. However, there is a code smell: the section evaluating additional is doubled in both constructors. The natural choice is then to extract it to another method:

class C
{
    private readonly DataType data;
    private readonly AdditionalType additional;

    private void EvalAdditional()
    {
        // LONG code evaluating additional
    }

    C(DataType newData)
    {
        data = newData;
        EvalAdditional();
    }

    C(OtherType newData)
    {
        // eval data from newData
        EvalAdditional();
    }
}

But then additional no longer can be readonly (beacuse it is not initialized in ctor).

How to solve this problem in an elegant way?

Upvotes: 0

Views: 62

Answers (3)

Chris
Chris

Reputation: 8656

You could do something like this:

C(DataType newData)
    :this ()
{
    data = newData;
}

C(OtherType newData)
    :this ()
{
    // eval data from newData
}

private C()
{
    EvalAdditional();
}

Although that depends heavily on what EvalAdditional is doing, you could pass parameters if required.

Upvotes: 0

Lee
Lee

Reputation: 144126

If the evaluation of additional does not depend on the arguments given to the other constructors, you can just move it to a private constructor and call that from your public constructors:

private C()
{
    //long code evaluating additional
}

C(DataType newData)
    : this()
{
    data = newData;
}

Upvotes: 2

Jeppe Stig Nielsen
Jeppe Stig Nielsen

Reputation: 61912

Just let the method EvalAdditional return the additional object (instead of void).

readonly DataType data;
readonly AdditionalType additional;

AdditionalType EvalAdditional()
{
    // LONG code evaluating additional
    return additional;
}

C(DataType newData)
{
    data = newData;
    additional = EvalAdditional();
}

C(OtherType newData)
{
    // eval data from newData
    additional = EvalAdditional();
}

Upvotes: 4

Related Questions