c# - 在 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; }
}
解决方案
对我来说,这是一个设计问题。当敌人之间的唯一区别只是点的值以及它们的名称时,定义类层次结构不是一个好主意。EnemyA
a和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;
}
}
推荐阅读
- jquery - 如何在带有 html、css 的幻灯片上使用半图像?
- python - 梳子:任何大于 40 的值都会返回无穷大?不知道为什么
- powershell - 如何使用 CSV 文件使用 Powershell 创建团队
- outlook - 在 Azure 逻辑应用程序中检查 Outlook 电子邮件附件的文件大小
- android - 由于 Google Play 控制台中的安全警报,YouTube 缩略图不可见
- docker - Dockerfile COPY 和 RUN 在一层
- drupal-8 - ^如何配置 phing build.xml 以使用 drupal aotoloader
- php - 如何在 laravel 中明智地设置 cron 用户
- events - Flutter BLoC - 如何将参数传递给事件?
- spring-boot - 无法通过 servlet.context.path 连接 websocket