Reputation: 22339
If I have a class like this:
public class Foo
{
public IEnumerable<Bar> Bars { get; set; }
public Foo()
{
Bars = new List<Bar>();
}
}
At some stage I re-factor the class and add a secondary constructor which implements the first one like this:
public class Foo
{
public IEnumerable<Bar> Bars { get; set; }
// some more properties were added
public Foo()
{
Bars = new List<Bar>();
}
public Foo(string parameter): this()
{
.... some code here
}
}
I could have also written it similar to this:
public class Foo
{
public IEnumerable<Bar> Bars { get; set; }
// some more properties were added too
public Foo()
{
InitilizeFoo();
}
public Foo(string parameter)
{
InitilizeFoo();
.... some code here
}
private void InitializeFoo()
{
Bars = new List<Bar>();
}
}
Seeing both approaches work in this scenario, is there a benefit or drawback in using one over the other?
Is inheriting constrcutors more efficient and making that code execute faster or is there a drawback which I don't know about making the second implementation more efficient instead?
Upvotes: 18
Views: 2258
Reputation: 38397
One of the key benefits in having one constructor call another constructor is that you can set read-only fields that way, you can't do that by calling a non-constructor method.
For example:
public class Foo
{
private readonly int myNumber;
public Foo() : this(42)
{
}
public Foo(int num)
{
myNumber = num;
}
}
Performance wise, it's probably no more or less efficient to call another constructor than to call another method, but it is more readable, in my opinion, for a constructor to call another constructor than to call a separate, private method whose only point is to be called by a constructor.
There could, of course, be situations when having a separate method makes sense, and it's certainly not "wrong" per se. Chaining constructors just reads better to many for most uses, and there is no negative performance impact.
UPDATE: I performed 10,000,000 iterations of each way (chained vs private initialization method) and the results were so close they were nearly indistinguishable:
Initializer Method took: 84 ms for 10,000,000 iterations, 8.4E-06 ms/each.
Chained Constructors took: 81 ms for 10,000,000 iterations, 8.1E-06 ms/each.
So really, performance-wise there is nearly no benefit either way. The main benefit is with chained constructors you can set readonly
fields, and in most cases it is more readable.
Upvotes: 28
Reputation: 15303
I may get burned for saying this but I prefer using default parameters in this case:
public Foo(string parameter = null)
{
}
I've had cases where I had 10 - 15 optional parameters and having 15 different constructors wasn't an elegant solution in my opinion. I think default parameters were only reintroduced in the 4.0 framework though.
Upvotes: 3
Reputation: 560
A benefit of having an Initialise() function is in case you would like to reset your object - you can simply call the init function again rather than delete & recreate the object.
Upvotes: 3
Reputation: 144122
Chaining constructors is a good way to enforce SRP and program flow. Hiding initialization code inside a standalone Initialize()
function could make sense if there are other situations in the object lifecycle where you might also want to "Initialize" it; perhaps if you wanted to be able to quickly instantiate and lazy-initialize it. But if the only valid time in the lifecycle to execute that functionality is during instantiation, and initialization is a well-defined set of discrete steps that need to be taken in order, then chaining facilitates that.
Upvotes: 6
Reputation: 5012
The key is to reduce the amount of duplicate code. In this case, calling the base constructor from a parameterized constructor reduces the chances of adding a bug later on after forgetting to update both of them.
Upvotes: 4