Why is it necessary for a base class to have a con

2019-04-03 05:49发布

问题:

This won't compile:

namespace Constructor0Args
{
    class Base
    {
        public Base(int x)
        {
        }
    }

    class Derived : Base
    {
    }

    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}

Instead, I get the following error:

'Constructor0Args.Base' does not contain a constructor that takes 0 arguments

Why is that? Is it necessary for a base class to have a constructor that takes 0 arguments?

回答1:

It isn't - the problem is that it needs to call some base constructor, in order to initialise the base type, and the default is to call base(). You can tweak that by specifying the specific constructor (and arguments) yourself in the derived-types constructor:

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

For parameters to base (or alternatively, this) constructors, you can use:

  • parameters to the current constructor
  • literals / constants
  • static method calls (also involving the above)

For example, the following is also valid, using all three bullets above:

class Derived : Base
{
    public Derived(string s) : base(int.Parse(s, NumberStyles.Any)) {}
}


回答2:

When you derive a class from another, the base class will be called before the derived classes constructor. When you don't explicitly call a constructor you are essentially writing

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

Since the Base class doesn't have a 0 argument constructor, this is invalid.



回答3:

If you don't explicitly define a constructor for a class, a default constructor is automatically defined, which looks like this:

public Derived() : base() 
{
}

You need to specify the constructor on the base class as well as which arguments to pass to it:

public Derived() : base(1) 
{
}


回答4:

This is becase when the child class is instantiated, it will also instantiate the base class. By default, it will try to find a arg less constructor. This is work with this code:

class Base
    {
        public Base(int x) { }
    }
    class Derived : Base
    {
        public Derived(int x)
            : base(x)
        {
        }
    }