Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is it not possible to use both :base() and :this() in a C# constructor

Tags:

c#

I have a default constructor in my class that initializes stuff.

I don't want copy/paste that into another constructor I have that needs to have :base(otherStuff) on it. I am guessing I will have to (or abstract it out to a method or some such thing).

But I am wondering, why are both not supported?

(Sometimes when I want something that the language does not support it means I am doing something wrong.)

Example:

public class SomeClass : SomeBase
{
      public SomeClass()
      {
          // Init a lot of lists and stuff
      }

      public SomeClass(OtherThings otherThings): base(otherThings)
             // :this()  <----- This is not legal syntax
      {
          // Do stuff with otherThings
      }
}
like image 550
Vaccano Avatar asked Mar 19 '23 14:03

Vaccano


2 Answers

I think the reasoning for this is the fact that base constructor is always executed before executing any constructor of your type which means that deriving from existing construtor c1() of your type already embedds deriving from base construtor b1() - and you obviously can't derive from 2 different base constrructors.

It's a bit confusing as this() constructor actually derives from base() constructor implicitly, so your code is equivalent to :

public class SomeClass : SomeBase
{
      public SomeClass(): **base()**
      {
          // Init a lot of lists and stuff
      }

      public SomeClass(OtherThings otherThings): base(otherThings)
             // :this()  <----- This is not legal syntax
      {
          // Do stuff with otherThings
      }
}

now it is obvious that you can't have SomeClass(OtherThings otherThings): base(otherThings):this() as compiler would not be able to execute 2 base constructors (base(otherThings) and base()).


UPD: Thinking of why it is prohibited to depend on 2 constructors I came into this example:

public class SomeBase {
    public SomeBase(){}

    public SomeBase(OtherThings otherThings):this(){}
}

public class SomeClass : SomeBase
{
      public SomeClass(): base()
      {
          // Init a lot of lists and stuff
      }

      public SomeClass(OtherThings otherThings): base(otherThings)
             // :this()  <----- This is not legal syntax
      {
          // Do stuff with otherThings
      }
}

Allowing to have SomeClass(OtherThings otherThings):base(otherThings):this() would result in SomeBase() being executed twice which is ridiculous and unexpected (once for :base(otherThings) and the other time for SomeClass(): base() which both depend on parameterless constructor base()).

like image 78
Isantipov Avatar answered Apr 29 '23 02:04

Isantipov


I don't know exactly why, but I had similar in the past and had to resort to something like...

public class SomeClass : SomeBase
{
      public SomeClass()
      {
          // Init a lot of lists and stuff
          CommonStuff();
      }

      public SomeClass(OtherThings otherThings): base(otherThings)
      {
          CommonStuff();

          // Do stuff with otherThings
      }

      private void CommonStuff()
      {
         // init common between both
      }
}
like image 27
DRapp Avatar answered Apr 29 '23 02:04

DRapp