39

C# in VS2005: if a class has two constructors, what is the best way for these constructors to share some code?

eg. How could I avoid having the x = 5 and y = 10 lines in both constructors for the following:

public class MyObject {

int x;
int y;
int z;

public MyObject() {
    x = 5;
    y = 10;
}

public MyObject(int setZ) {
    x = 5;
    y = 10;
    z = setZ;
}
CJ7
  • 22,579
  • 65
  • 193
  • 321

4 Answers4

74

Just chain to the common constructor...

public MyObject(int setZ)
  : this()
{
  z = setZ;
}
Rob
  • 5,525
  • 1
  • 24
  • 26
  • 6
    Will this cause the base constructor to be executed if the class is inherited? – CJ7 Jun 30 '10 at 03:03
  • @CJ7 Yes. The constructor of base class/parent chain is/are always executed first before the constructor of current class gets executed. You can read about it more [here](https://stackoverflow.com/q/9171629/465053). – RBT Feb 14 '18 at 11:34
  • [This](https://stackoverflow.com/q/1882692/465053) thread has more information on constructor chaining. – RBT Feb 14 '18 at 11:44
10

Use the this() syntax.

public MyObject(int setZ) : this() {
    z = setZ;
}
Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
5

Create another method:

private setDefaultNumbers() {
    x = 5;
    y = 10;
}

Then have both versions of your constructor call this method:

public MyObject() {
    setDefaultNumbers();
}

public MyObject(int setZ) {
    setDefaultNumbers();
    z = setZ;
}
Alex Miller
  • 1,566
  • 1
  • 13
  • 16
  • I would only recommend this if setDefaultNumbers is something you could see calling after the object is created. Even if it is private, there is no way to mark it as 'for constructors only' unless it is in the constructors only. If you can I would prefer the chained constructors, unless there is no way to cleanly chain them. – Dolphin Jun 30 '10 at 03:01
  • 1
    FYI, there are two advantages of using a setup routine over a nested constructor call: (1) The outer constructor can run arbitrary code before the common setup routine; (2) The setup routine can be wrapped in a try/finally block to ensure that any IDisposable objects created before the setup routine was run will be cleaned up if the setup routine throws an exception. In some cases, it may be helpful for an extensible base class to have all its public constructors call a protected setup routine, but have a protected constructor which does not. Derived class constructors could... – supercat Jul 11 '11 at 17:30
  • ...call the protected constructor and then call the setup routine themselves. Obviously this pattern would require some care, but in scenarios where the derived class needs to create some IDisposable objects and pass them to the inner "constructor" it's probably the safest pattern. Note that calling base.new(new SomeDisposableType) is a dangerous pattern which cannot be made safe if there's any possibility that base.new could throw. – supercat Jul 11 '11 at 17:33
3

It's very similar to the way you'd do it with methods. Normally you would do something like:

public void SetA(int a)
{
    this.a = a;
}

public void SetAandB(int a, int b)
{
    this.SetA(a);
    this.b = b;
}

with constructors, there's special syntax for it:

public void MyObject()
{
    this.a = 5;
}

public void MyObject(int b)
    : this()
{
    this.b = 10;
}
Steven Evers
  • 16,649
  • 19
  • 79
  • 126