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