这个问题可能听起来很奇怪,也请原谅我,因为我的程序流程可能都错了,但对我的情况有任何帮助都非常感谢!
我有一个名为EnemyFighter
的类,它包含HP,攻击强度等所有信息。当程序启动时,它会将不同类型的敌人添加到列表中,如下所示:
// Build enemies
Enemies = new Dictionary<int, EnemyFighter>();
Enemies.Add(1, new EnemyFighter());
Enemies[1].Name = "Beaver";
Enemies[1].SetLevel(1);
Enemies.Add(2, new EnemyFighter());
Enemies[2].Name = "Unicorn";
Enemies[2].SetLevel(3);
然后我有敌人团体,所以你可以打多个敌人,也许两个海狸可以说:
// Enemy groups
EnemyGroups = new List<EnemyFighter[]>();
EnemyGroups.Add(new EnemyFighter[] { Enemies[1] }); // Beaver
EnemyGroups.Add(new EnemyFighter[] { Enemies[1], Enemies[1] }); // Beaver x2
EnemyGroups.Add(new EnemyFighter[] { Enemies[2] }); // Unicorn
但是当我去运行应用程序时,在攻击其中一个敌人时(当对抗两个海狸时)我意识到我正在攻击&#34;两者都是&#34;因为基本上都是&#34;海狸&#34;是同一个对象。
有人可以告诉我更好的方法来设置这种情况,我有一个对象的模板,但想要将它的唯一版本传递到列表中。像这样:
EnemyGroups.Add(new EnemyFighter[] { new Enemies[1], new Enemies[1] });
再次提前感谢任何帮助!
答案 0 :(得分:2)
&#34;复制&#34;对象不是一件小事,在大多数情况下也是不可取的。
在这种情况下,最好的方法可能是做这样的事情:
public class EnemyPrototype
{
public string Name { get; set; }
public int Level { get; set; }
}
public class EnemyProvider
{
private Dictionary<string, EnemyPrototype> _prototypes =
new Dictionary<string, EnemyPrototype>();
public void AddPrototype(string key, EnemyPrototype prototype)
{
_prototypes[key] = prototype;
}
public EnemyFighter GetEnemy(string key)
{
var prototype = _prototypes[key];
var fighter = new EnemyFighter();
fighter.Name = prototype.Name;
fighter.SetLevel(prototype.Level);
return fighter;
}
}
现在你可以像这样创建你的新敌人原型(假设一个名为EnemyProvider
的私人_provider
实例成员 - 调整你的结构):
_provider = new EnemyProvider();
_provider.AddPrototype("Beaver", new EnemyPrototype {Name = "Beaver", Level = 1});
得到一个像这样的新人:
var enemy = _provider.GetEnemy("Beaver");
所以加入你的两个海狸就变成了:
EnemyGroups.Add(new EnemyFighter[] { _provider.GetEnemy("Beaver"),
_provider.GetEnemy("Beaver") });
您还可以在EnemyProvider
课程中添加一个方法,让您传递int
并为您提供一系列敌人!
答案 1 :(得分:0)
因此,正如你所说,你攻击两者的原因是它们本质上是同一个对象。要解决此问题,您应该复制该对象。您可以创建一个这样的方法:
private EnemyFighter DuplicateEnemy(EnemyFighter original){
var newEnemy = new EnemyFighter(){
Name = original.Name
};
newEnemy.setLevel(original.Level);
return newEnemy;
}
EnemyGroups.Add(new EnemyFighter[] { DuplicateEnemy(Enemies[1]) }); // Beaver
EnemyGroups.Add(new EnemyFighter[] { DuplicateEnemy(Enemies[1]), DuplicateEnemy(Enemies[1]) }); // Beaver x2
EnemyGroups.Add(new EnemyFighter[] { DuplicateEnemy(Enemies[2]) }); // Unicorn
这将返回具有相同值的新对象,您可以将其添加到列表中。
您还可以查看AutoMapper,它是一个用于复制对象的库,非常灵活,我以前在项目中使用它,发现它非常有用。 http://automapper.org/
答案 2 :(得分:0)
您可以使用MemberwiseClone()
方法创建&#39;模板的浅表副本。将它添加到字典中时的对象。
https://msdn.microsoft.com/en-us/library/system.object.memberwiseclone.aspX
或者您可以实现一种方法来制作对象的深层副本。
上面的MemberwiseClone()
链接中提供了创建浅拷贝和深拷贝的示例。
答案 3 :(得分:0)
正如您所注意到的,您在阵列中多次引用同一个对象。底线是你需要放入不同的新对象而不是相同的引用。
我推荐的做法是建造某种能够创造和回归新敌人的工厂。这样做的好处是能够从一般的敌人阵营中创造一个敌人,而不必担心你在克隆之前所做的任何修改。
public static class EnemyFactory
{
public static EnemyFighter MakeBeaver()
{
var beaver = new EnemyFighter
{
Name = "Beaver",
Level = 1
};
return beaver;
}
}
然后使用工厂创建实例:
EnemyGroups.Add(new EnemyFighter[] { EnemyFactory.MakeBeaver(), EnemyFactory.MakeBeaver() }); // Beaver x2
答案 4 :(得分:0)
我认为你需要&#34;克隆&#34;你的初始对象。请查看MSDN中的ICloneable
界面文档和示例:https://msdn.microsoft.com/en-us/library/system.icloneable.clone(v=vs.100).aspx