When are derived constructor classes forced to use the base keyword?

C # 6.0 in a nutshell by Joseph Albahari and Ben Albahari (OReilly).

Copyright 2016 Joseph Albahari and Ben Albahari, 978-1-491-92706-9.

declares the following on page 96 after introducing an implicit invocation of the base class constructor without parameters:

If the base class does not have an accessible constructor without parameters, subclasses are forced to use the base keyword in their constructors.

I am trying to create a code snippet to confirm this, but have not succeeded yet.

My snippet:

 public class X { public int Num { get; set; } public void Method_1() { Console.WriteLine("X"); } public virtual void Method_2() { Console.WriteLine(Num); } } public class Y : X { public Y() { Num = 1000; } } private static void Main(string[] args) { new Y().Method_2(); } 

I was expecting to get a compiler error following the statement of the book, but I am not getting it. The code starts and prints 1000 correctly.

My question is: what does a book with a subclass that are forced to use the base keyword mean? I am trying to reproduce such a scenario.

What am I missing?

+6
source share
3 answers

Class Y has access to a dimensionless constructor for base class X , because if the class does not define a constructor, there is an implicit constructor without parameters.

If you write:

 public class X { public X(int i){} } 

Then there will be no more parameterless constructor X in Y .

+10
source

The problem arises from a misunderstanding of your sample code. Since you did not define any constructor in class X , C # defined implicit for you. This implicit constructor is a no-arg constructor.

The quote you mention refers to the case when you wrote a constructor other than the standard one.

Writing a constructor other than the default suppresses the generation of an implicit constuctor. This means that you are forced to explicitly call another constructor from the constructor of the Dervived class using the base keyword

  class BaseClass { public BaseClass(int i) {} } class Derived : BaseClass { public Derived() : base(44) { } } 
+5
source

The same rules except ...

This is actually no different from the usual rules for accessing members of any other member of the base class.

A constructor is a bit more than a regular function.

The key difference is that the derived class automatically tries to call the base constructor. In particular, a basic constructor that does not accept parameters.

If the constructor does not exist, you will receive an error message. If it exists, but you do not have β€œpermission” to access it, you will receive an error message.

If you do not specify any constructors at all for the base class, then it is assumed that this class has a constructor without parameters, which does nothing.

Set a different path if you do not specify a constructor that is implicitly created for you.

Here are 7 examples of when you will not face this problem:

Example 3 - OK - an empty default constructor is implied

  class Base { // No constructor explicitly defined so a default constructor is assumed // Having no constructor at all is like having an empty constructor // Like this: Base() { } } class Derived : Base { // OK - Explicitly calling accessible base constructor public Derived() { } } 

Example 2 - OK - Available Base Constructor

  class Base { // "public" so it accessible by derived class public Base() { } // no parameters - aka parameterless } class Derived : Base { // OK - implicitly calls accessible parameterless constructor base() public Derived() {} } 

Example 3 - OK - Protected funds are still available

  class Base { // "protected" so it accessible by derived class protected Base() { } // no parameters - aka parameterless } class Derived : Base { // OK - implicitly calls accessible parameterless constructor base() public Derived() {} } 

Example 4 - FAIL - Private Not Available

  class Base { // "private" so it NOT accessible by derived class private Base() { } // no parameters - aka parameterless } class Derived : Base { // FAIL - tries to implicitly call parameterless constructor base() // ERROR CS0122 - Base.Base() is inaccessible due to it protection level public Derived() { } } 

Example 5 - FAIL - always trying to call a constructor without parameters

  class Base { // "private" so it NOT accessible by derived class private Base() { } // no parameters - aka parameterless // "protected" so it accessible by derived class protected Base(int a) { } // has parameter - aka NOT parameterless } class Derived : Base { // FAIL - STILL tries to implicitly call parameterless constructor base() // ERROR CS0122 - Base.Base() is inaccessible due to it protection level public Derived() { } } 

Example 6 - FAIL - If this does not exist, then it is assumed that you call another

  class Base { // notice there is not parameterless constructor // just one constructor does does have parameters // "protected" so it accessible by derived class protected Base(int a) { } // has parameter - aka NOT parameterless } class Derived : Base { // FAIL - STILL tries to implicitly call parameterless constructor base() which doesn't exist // ERROR CS7036 - There is no argument given that corresponds to the required formal parameter 'a' of Base.Base(int) public Derived() { } } 

Example 7 - OK - if you do not name yourself

  class Base { // "private" so it NOT accessible by derived class private Base() { } // no parameters - aka parameterless // "protected" so it accessible by derived class protected Base(int a) { } // has parameter - aka NOT parameterless } class Derived : Base { // OK - Explicitly calling accessible base constructor with `int` parameter public Derived() : base(10) { } } 
0
source

All Articles