this() and base() constructors in C#

2.5k views Asked by At

There seems to be no language syntax for specifying both a this() and a base() constructor. Given the following code:

public class Bar : Foo
{
    public Bar()
      :base(1)
      //:this(0)
    { }
    public Bar(int schmalue)
      :Foo(1)
    {
       //Gobs of initialization code
       ...
       Schmalue = schmalue;
    }

    public int Schmalue { get; private set; }
}

public class Foo
{
    public Foo()
    {
        Value = 0;
    }

    public class Foo(int value)
    {
        Value = value;
    }

    public int Value { get; private set; }
}

The compiler gives me an error stating that '{' was expected when uncommenting the :this(0) call. This is bothersome because it causes me to factor out my code into a private method, when this functionality was clearly provided to prevent such a thing.

Am I simply doing this wrong? I've attempted no separator, semi-colon, comma... It seems this was just an oversight from the dev team. I'm interested in why this was omitted, if I'm going about this the wrong way or if anybody has good suggestions for alternatives.

5

There are 5 answers

1
Jeff Sternal On BEST ANSWER

You can accomplish this by invoking the base constructor at the end of your chain:

public Bar(): this(0) {}
public Bar(int schmalue): base(1) {
    // ... initialize
}
0
Jon Skeet On

No, you can only chain to a single constructor - either another constructor in the same class or a base constructor.

It's not really clear what you're trying to do. Typically I find it's worth creating one "primary" constructor in a derived class: all the other constructors within the derived class use "this" to call the primary one, which calls "base" to call the appropriate base constructor.

While that model doesn't fit every scenario - in particular when you want to call different base constructors from different derived constructors - it's usually a good model.

0
Darin Dimitrov On

In your design I can't see many common things between the Bar and Foo classes. Why does Foo derive from Bar when you reimplement everything? Both classes have an integer property with public getter and private setter and both classes have default constructors and a constructor allowing to initialize the integer property. So why do those two classes exist anyways?

0
matthias.lukaszek On

The second ctor in Bar is simply wrong. Try:

public Bar(int schmalue)
  :base(1) //would call Foo(1)
{
   //Gobs of initialization code
   ...
   Schmalue = schmalue;
}

The comment in the first ctor seems to mean something like

  • initialize Bar with schmalue = 0

  • call base ctor Foo with value = 1

Right?

To do that, replace the second ctor and simply add another (private) ctor that can handle both values

public Bar(int schmalue)
  :this(1, schmalue) //would call Bar(1, schmalue)
{
}

private Bar(int value, int schmalue)
 :base(value)
{
    //Gobs of initialization code
   ...
   Schmalue = schmalue;
}
0
Adam Wright On

Consider what would happen if you could call both this and base as constructors in one constructor. Let's assume that first the base constructor would be called. Then, the this constructor would be called - which itself will call the base constructor. Thus, the base class would be instantiated twice. This breaks the semantics of constructors - namely, that an object is constructed once.

As such, calling both base and this is forbidden. Let your delegated this constructor call the base with specific parameters, if it needs to.