Reputation: 25927
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
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
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
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