How can I use multiple constructors to remove duplicated code while maintaining readability?

Solution 1:

As an alternative to calling an initialization method from all constructors (which prevents you from using readonly fields) or factory methods (which introduce additional complexity when you have derived classes), you can use a parameter object:

int a, b, c;

public Constructor()
    : this(new ConstructorParameters())
{
}

public Constructor(int x, int y)
    : this(new ConstructorParameters(x, y))
{
}

public Constructor(int x, int y, int z)
{
    a = x;
    b = y;
    c = z;
    //do stuff 
} 

private Constructor(ConstructorParameters parameters)
    : this(parameters.X, parameters.Y, parameters.Z)
{
}

private class ConstructorParameters
{
    public int X;
    public int Y;
    public int Z;

    public ConstructorParameters()
    {
        AnotherThing at = new AnotherThing(param1, param2, param3); 
        Something st = new Something(at, 10, 15) 
        SomethingElse ste = new SomethingElse("some string", "another string"); 

        X = st.CollectionOfStuff.Count; 
        Y = ste.GetValue(); 
        Z = (int)Math.Floor(533 / 39.384); 
    }

    public ConstructorParameters(int x, int y)
    {
        X = x;
        Y = y;
        Z = (int)Math.Floor(533 / 39.384);
    }
}

Solution 2:

You can do

Constructor() : this(5, 10, 15)
{
}
Constructor(int x, int y) : this(x, y, 15)
{
}
Constructor(int x, int y, int z)
{
  int a = x;
  int b = y;
  int c = z;
  //do stuff
}

However if you need to do some fancy logic depending on the parameters, I would use a factory pattern:

public class myclass
{
  private myclass(int x, int y, int z)
  {
    int a = x;
    int b = y;
    int c = z;
    //do stuff
  }
  public static myclass Create()
  {
    AnotherThing at = new AnotherThing(param1, param2, param3);
    Something st = new Something(aThing, 10, 15)
    SomethingElse ste = new SomethingElse("some string", "another string");

    int x = thing.CollectionOfStuff.Count;
    int y = ste.GetValue();
    int z = (int)Math.Floor(533 / 39.384);

    return new myclass(x, y ,z);
  }
  public static myclass Create(int x, int y)
  {
    if (x = 1)
      return new myclass(x, y, 2)
    else 
      return new myclass(x, y, 15);
  }
  public static myclass Create(int x, int y, int z)
  {
    //so on and so forth
    return new myclass(x, y, z);
  }
}

Although you don't need a factory pattern, it definitely makes your constructor logic readable.