user11416547
user11416547

Reputation:

Base() and This() in constructors. (Chained constructors)

I have a question regards chaining constructors I read some question on StackOverflow and some c# articles but I cannot understand the topic fully. So I have a BaseClass that is inherited by DerivedClass. In the DerivedClass, I have no argument constructor but it's calling the base constructor using: base() and it also passing a value. Is this the primary purpose of the base keyword used in the constructor to pass a value to the inherited class from the derived one or is something more out there. And also in the derived class, we have a second constructor that takes 1 parameter and its using: this(). I can't understand why when I remove: this() from this constructor "VS" tells me "There is no argument given that corresponds to the required formal parameter "i" of BaseClass.BaseClass(int) ? Why I can't just have one argument constructor in the DerivedClass without using this()?

public class BaseClass
{
    protected int _Num;

    public BaseClass(int i)
    {
        _Num = i;
    }

    public int Num { get => this._Num ; set => _Num = value; }
}

public class DerivedClassA : BaseClass
{
    private string _Name;
    private int _AnotherValue;

    public string Name { get => this._Name ; set => this._Name = value; }
    public int AnotherValue { get => this._AnotherValue; set => this._AnotherValue = value; }

    public DerivedClassA() : base(123)
    {
        _Name = "testing";
    }

        public DerivedClassA(int param2) : this()      <-- Why i can't compile the program without the this() keyword here ?
        {
            AnotherValue = param2;
        }
    }

public class Program
{
        public static void Main(string[] args)
        {
            DerivedClassA objA = new DerivedClassA(5);
        }
}

Upvotes: 0

Views: 81

Answers (1)

ProgrammingLlama
ProgrammingLlama

Reputation: 38737

I can't find a duplicate that exactly matches, so I'll provide an answer.

Imagine these classes:

public class Base
{
    public Base()
    {
    }
}

public class Derived : Base
{
    public Derived()
    {
    }
}

Try it online

When you initialize a derived class, you have to first initialize the base. In our example above, the Base class has a parameterless constructor, so the derived class can implicitly call it. If we add a base second constructor, this logic remains true, and the parameterless constructor will still be implicitly called:

public class Base
{
    public Base()
    {
    }

    public Base(int a)
    {
    }
}

public class Derived : Base
{
    public Derived()
    {
    }
}

Try it online

But if we take away the parameterless constructor, Derived must now call the base constructor explicitly:

public class Base
{       
    public Base(int a)
    {
    }
}

public class Derived : Base
{
    public Derived() : base(1)
    {
    }
}

Try it online

So what happens if we add an extra derived class constructor? Well, that also has to call the base class (either directly, or indirectly):

public class Base
{       
    public Base(int a)
    {
        // this method body is executed first
    }
}

public class DerivedA : Base
{
    public DerivedA(string name, int val) : base(val)
    {
        // this method body is executed second (last if you used this constructor, e.g. new DerivedA("hello", 1) )
    }

    public DerivedA() : this("test", 5) // this will call the constructor above, which will first call base. So the final chain is: base, constructor above, this constructor
    {
        // this method body is executed third (last if you used this constructor, e.g. new DerivedA() )
    }
}

public class DerivedB : Base
{
    public DerivedB(string name, int val) : base(val)
    {
    }

    public DerivedB() : base(5) // this will call the base constructor, and then this constructor. The constructor above will not be used.
    {

    }
}

Try it online

Note that all classes have a parameterless constructor when no other constructor is defined, so the following two examples are equivalent:

public class BaseA
{

}

public class BaseB
{
    public BaseB()
    {
    }
}

You'll note that SharpLab shows the compiler removed the empty constructor from BaseB() since it's superfluous.

Finally, a derived class without an explicitly defined constructor, will still call the base class constructor implicitly:

public class Base
{       
    public Base()
    {
        // this method body is executed first
        Console.WriteLine("Base constructor");
    }
}

public class Derived : Base
{
}

Try it online

So to summarise: unless your base class has a parameterless constructor, your derived class constructors have to either call a base constructor directly, or indirectly through another derived class constructor. Obviously you only need to call a single base constructor method, as with any other class instantiation. You don't need matching derived methods for each base method, so long as you can construct the base with the values you do have.

Upvotes: 3

Related Questions