首页 > 解决方案 > 如何在 C# 中使用抽象类

问题描述

我正在尝试在控制台中制作游戏(这有点简单)。我想有多种类型的士兵,所以我想我会做一个抽象的士兵类

public abstract class Soldier
    {
        public string Name;
        public int Health;
        public float ShootingRange;
        public float MovementRange;
        public Player Owner;
        public Vector2Int Position;
        public char Symbol;
    }

这样做的原因是我想要一个玩家拥有的所有单位的列表。播放器类如下所示:

 public class Player
{
    public int Money = 0;
    public ConsoleColor Color;

    public List<Soldiers.Soldier> Units = new List<Soldiers.Soldier>();

    public Player(ConsoleColor c)
    {
        Color = c;
    }

    public void AddUnit(Vector2Int Position)
    {
        Units.Add(new Soldiers.Rifleman(this, Position));
    }
}

然后我想实现一个版本的士兵类来制作一种士兵,我称之为步枪兵:

public class Rifleman : Soldier
    {
        public int Health = 10;
        public float ShootingRange = 5f;
        public float MovementRange = 2.5f;
        public Player Owner;
        public Vector2Int Position;
        public char Symbol = Utils.MASTERKEY["Rifleman"];

        public Rifleman(Player owner, Vector2Int position)
        {
            Owner = owner;
            Position = position;
        }
    }

问题是,在我的地图类(我如何显示和管理游戏)中,当我尝试在地图上拉出代表 Rifleman 类的字符时,它发现它是一个空值。我该如何解决这个问题?

标签: c#

解决方案


正如@Progman 和@bmm6o 所说,您正在重新定义您的Symbol领域。由于您List<Soldier>返回 a Soldier,因此它的Symbol字段是您得到的,没有分配。

您应该使用可以覆盖的抽象和/或虚拟属性,或者使用受保护的 setter 属性,如下面的示例中显示的不同形式。

public abstract Soldier
{
  public abstract char Symbol { get; }
  public virtual string Name { get; } = "Soldier";
  public string Weapon { get; protected set; } = "Gun";
}

public Rifleman : Soldier
{
  public override char Symbol => 'r';
  public override string Name => nameof(Rifleman);
}

public Sniper : Soldier
{
  public Solder()
  {
    Weapon = "Rifle";
  }
  public override char Symbol => 's';
}

字段几乎应该始终是私有的,并且在现代版本的 C# 中通常是不必要的(您在上面看到的是应该适用于任何 .NET Framework 或 Core 版本的语言功能)。


推荐阅读