Home > Enterprise >  If my 2 class constructors have the same number of args, why does it matter that the base class'
If my 2 class constructors have the same number of args, why does it matter that the base class'

Time:04-26

namespace DnD
{
    class Player : Creature
    {
        Race race;
        Spell[] cantrips = new Spell[16];
        public Player(Race inputRace)
        {
            race = inputRace;         
        }

        void castSpell(Spell spell)
        {
            
        }
    }

    class Creature
    {
        String name;
        public int hp;

        Creature(string inputName)
        {
            name = inputName;
        }
    }
}

For some reason, this code gives me an error that the base class (creature) has a constructor with more that zero args, with the exact error message being: 'Creature' does not contain a constructor that takes 0 arguments'

I have seen something like this on another post, though there the base class' constructor has 1 arg and the derived class' had zero but in this case they both have 1.

Also this code is from my project where i am tryng to somewhat make dnd in c#.

CodePudding user response:

You just need to call the base class constructor with :base (someString). You don't show the Race class here, but if it had a string RaceName property, you could pass that to the base class constructor.

public Player(Race inputRace)
    : base (inputRace.RaceName)
{
    race = inputRace;         
}

Also, consider if the Creature class should ever have a concrete instance. This is probably a good candidate for an abstract class.

CodePudding user response:

You're missing the fact that if you don't write :base(...) after your constructor definition, C# writes :base() for you (and to be fair, it isn't obvious)

Every constructor has to make a call to a base constructor, all the way up the descent tree to object. If you don't provide instruction on which constructor to call C# calls one for you (invisibly). If there isn't such a constructor, C# cannot sort that out itself automagically; you have to provide direction

If you don't provide a constructor, C# provides an empty one that does nothing, just so it can establish a chain. If you do provide one, it doesn't provide one (but it might still modify yours to call base)

So, if you write:

class NoConstructor{


}

C# modifies it to:

class NoConstructor{

  NoConstructor():base(){}
}

If you write:

class ConstructorNoBase{
  ConstructorNoBase(){}
}

C# modifies it to:

class ConstructorNoBase{
  ConstructorNoBase():base(){}
}

If you write:

class ConstructorWithBase{
  ConstructorWithBase():base{}
}

C# leaves it alone


You can this reach a situation where you have:

class Parent{
  Parent(int arg){

  }
}

class Child:Parent{

}

class Child2:Parent{
  Child2(int arg){

  }
}

And C# modifies them to:

class Parent{
  Parent(int arg):base(){ //no problem; object has a no-arg constructor

  }
}

class Child:Parent{
  Child():base(){    //problem, there isn't a no-arg base constructor
  }
}

class Child2:Parent{
  Child2(int arg):base(){   //problem, there isn't a no-arg base constructor

  }
}

Particularly in the second case, C# won't look at Child2 and go "oh, there is a int arg constructor on the parent, and int arg on the child, I'll call base(arg)" - it just puts base() in

To stop it creating this "call to something that doesn't exist" you either have to:

  • provide the thing it is calling so it does exist
  • provide your own call to base(...) to stop c# inserting its own call
  • Related