Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I tell the inheriting class to not call its base class' parameter-less constructor?

I was surprised to find out that the parameter-less constructor of my base class is called any time I call any constructor in a derived class. I thought that is what : base() was for, to explicitly call the base constructor if and when I want to.

How can I prevent the base constructor from being called when I instantiate a derived class?

using System;

namespace TestConstru22323
{
    class Program
    {
        static void Main(string[] args)
        {
            Customer customer = new Customer("Jim", "Smith");
            Customer c = new Customer();
            Console.WriteLine(customer.Display());

            Console.ReadLine();
        }
    }

    public class Person
    {
        public Person()
        {
            Console.WriteLine("I don't always want this constructor to be called. I want to call it explicitly.");
        }
    }

    public class Customer : Person
    {
        private string _firstName;
        private string _lastName;

        //public Customer(string firstName, string lastName): base()  //this explicitly calls base empty constructor
        public Customer(string firstName, string lastName) //but this calls it anyway, why?
        {
            _firstName = firstName;
            _lastName = lastName;
        }

        public string Display()
        {
            return String.Format("{0}, {1}", _lastName, _firstName);
        }
    }
}
like image 695
Edward Tanguay Avatar asked Jul 16 '10 14:07

Edward Tanguay


3 Answers

The only way is to explicitly tell it which other base ctor you want it to call; which of course means you must choose some base ctor to call.

You can't have it call no base ctor at all - conceptually, constructing a Customer is done by first constructing a Person, and then doing Customer specific construction on top of it. For example, suppose Person had private fields - how would these be correctly constructed if construction of a Customer was allowed to not first construct a Person?

like image 75
AakashM Avatar answered Nov 12 '22 19:11

AakashM


In .NET, every object constructor in an object hierarchy will be called regardless if you call :base() or not.

:base() is implicitly called if you don't explicitly call it.

:base() can be used if you want to call a different contructor on a parent object rather than the default constructor.

If you have code in the parent constructor that should not be called everytime, it may be better to move that code to it's own method that will need to be called explicitly after the object is constructed. Or, create a parameterized constructor on the parent object and use the parameter to determine if the code should be executed or not.

For example:

:base(true) - This executes your code.
:base(false) - This does not execute your code.
like image 8
ChrisNel52 Avatar answered Nov 12 '22 18:11

ChrisNel52


As others have pointed out, a derived instance must call call one of its base class' constructors.

If you want to control the execution of a base class' initialization logic, remove its default constructor and replace it with something like this:

public class Base {
    // Base has no default constructor
    public Base(bool initialize) {
        if (initialize) {
            // ... logic here 
        }
    }    
}

And the derived constructors look like this:

// Derived1 executes the initialization logic
public Derived1(): base(true) {}

// Derived2 does not
public Derived2(): base(false) {}
like image 2
Jeff Sternal Avatar answered Nov 12 '22 19:11

Jeff Sternal