如果我的 2 个 class 构造函数具有相同数量的参数,为什么基础 class 的构造函数没有 0 个参数很重要?

If my 2 class constructors have the same number of args, why does it matter that the base class's constructor doesn't have 0 args?

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;
        }
    }
}

出于某种原因,这段代码给我一个错误,即基础 class(生物)的构造函数的参数多于零,确切的错误消息是: 'Creature' does not contain a constructor that takes 0 arguments'

我在另一个 post 上看到过类似的东西,尽管基础 class' 构造函数有 1 个 arg 而派生 class' 有零但在这种情况下它们都是有 1.

此代码也来自我的项目,我正在尝试在 C# 中制作 dnd。

您只需使用 :base (someString) 调用基础 class 构造函数。你没有在这里显示 Race class,但如果它有一个 string RaceName 属性,你可以将它传递给基础 class 构造函数。

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

此外,请考虑 Creature class 是否应该有一个具体实例。这可能是摘要 class.

的一个很好的候选者

您错过了 如果您不在构造函数定义后编写 :base(...),C# 会为您编写 :base()(并且公平地说,这并不明显)

每个构造函数都必须调用基构造函数,沿着下降树一直向上到对象。如果您不提供有关调用哪个构造函数的说明,C# 会为您调用一个(不可见)。如果没有这样的构造函数,C# 无法自动解决它;你必须提供方向

如果您不提供构造函数,C# 会提供一个不执行任何操作的空构造函数,以便它可以建立一个链。如果您确实提供了一个,它不会提供一个(但它可能仍会修改您的呼叫基地)

所以,如果你写:

class NoConstructor{


}

C#修改为:

class NoConstructor{

  NoConstructor():base(){}
}

如果你写:

class ConstructorNoBase{
  ConstructorNoBase(){}
}

C#修改为:

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

如果你写:

class ConstructorWithBase{
  ConstructorWithBase():base{}
}

C# 不用管它


您可以达到以下情况:

class Parent{
  Parent(int arg){

  }
}

class Child:Parent{

}

class Child2:Parent{
  Child2(int arg){

  }
}

而 C# 将它们修改为:

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

  }
}

特别是在第二种情况下,C# 不会查看 Child2 并去“哦,父级有一个 int arg 构造函数,子级有 int arg,我会调用base(arg)" - 它只是将 base() 放入

要阻止它创建此“调用不存在的东西”,您必须:

  • 提供它正在调用的东西,这样它确实存在
  • 提供你自己对 base(...) 的调用以阻止 c# 插入它自己的调用