首页 > 解决方案 > 在 C# 中使用抽象类的困惑

问题描述

我有一个问题,因为我是编程新手我真的很困惑如何为以下问题实施最佳实践解决方案,它是一个游戏逻辑,这里是可能的积分方式

EnemyA 400,
EnemyB 500,
EnemyC 700,
Coin   200,
FireBall 300

意味着击球Coin给你200分,投篮FireBall给你300分……

如果您达到 1000 分,您将获得额外的生命,逻辑简单但实施最佳实践不是(至少对我而言)我应该使用abstract class还是Dictionary

到目前为止,我使用了一个Dictionary,我读取了一个给定的文件 (txt) 文件,该文件写入 (EnemyA,EnemyB,Coin,Coin,Coin,Coin) 然后我计算点数:

public int pointCal(IEnumerable<string> enemyType)
{
    var possiblePoints = new Dictionary< EnemisEntity,int>()
    {
        {new EnemisEntity{enemyType="EnemyA"},400 },
        {new EnemisEntity{enemyType="EnemyB" },500 },
        {new EnemisEntity{enemyType="EnemyC"},700 },
        {new EnemisEntity{enemyType="Fireball"},300 },
        {new EnemisEntity{enemyType="Coin"},200 },
    };
    int z=0;
    List<int> myPoints=new List<int> ();         
    foreach (var item in enemyType)
    {
        z = possiblePoints.FirstOrDefault(f => f.Key.enemyType.Equals(item)).Value;
                myPoints.Add(z);
    }
    int finalPonts= g.Sum(s=>Convert.ToInt32(s));
    return finalPonts;
}


  Enemy entity class:

     public  class EnemisEntity
    {
       public string enemyType { get; set; }
       
     }

标签: c#

解决方案


对我来说,这是一个设计问题。当敌人之间的唯一区别只是点的值以及它们的名称时,定义类层次结构不是一个好主意。EnemyAa和class之间的唯一区别EnemyB就是每个 class 中包含的值。因此,您可以使用单个通用类来保存每个敌人的信息并处理点数。

下面是我可以编写的实现此设计的最简单的工作原型。它依赖于两个类。EnemyEntity保存敌人类型及其分数的类,以及包含Game评分和记录所有可能敌人的逻辑的类。

public class EnemyEntity
{
    public EnemyEntity(string type, int points)
    {
        Type=type;
        Points=points;
    }

    public string Type { get; }
    public int Points { get; }
}

public class Game
{
    public Game(params (string type, int points)[] values)
    {
        this.Enemies = new List<EnemyEntity>();
        foreach (var (type, points) in values)
        {
            Enemies.Add(new EnemyEntity(type, points));
        }
    }

    public List<EnemyEntity> Enemies { get; }

    public int CalculatePoints(IEnumerable<string> targets)
    {
        int points = 0;
        foreach (var item in targets)
        {
            var target = Enemies.FirstOrDefault((enemy) => enemy.Type.Equals(item));
            if (target!=null)
            {
                points+= target.Points;
            }
        }
        return points;
    }

}


class Program
{
    static void Main(string[] args)
    {
        var game = new Game(
            ("EnemyA", 400),
            ("EnemyB", 500),
            ("EnemyC", 700),
            ("Coin", 200),
            ("FireBall", 300));

        var input = "EnemyA,EnemyB,Coin,Coin,Coin,Coin";
        var targets = input.Split(',');
        var points = game.CalculatePoints(targets);

        Console.WriteLine(points);
        // 1700
    }
}

笔记:

最简单的方法是使用 aList<EnemyEntity>并使用.FirstOrDefault(). 我可以使用 aDictionary<string,EnemyEntity>来简化查找过程。这是Game使用字典更改类的方式。

public class Game
{
    public Game(params (string type, int points)[] values)
    {
        this.Enemies = new Dictionary<string, EnemyEntity>();
        foreach (var (type, points) in values)
        {
            Enemies[type] = new EnemyEntity(type, points);
        }
    }

    public Dictionary<string, EnemyEntity> Enemies { get; }

    public int CalculatePoints(IEnumerable<string> targets)
    {
        int points = 0;
        foreach (var item in targets)
        {
            var target = Enemies[item];
            if (target!=null)
            {
                points+= target.Points;
            }
        }
        return points;
    }

}

推荐阅读