我已经搜索了可能导致意外输出的原因(至少对我来说)并且我没有走得太远。我认为它与类作为引用类型有关,但我很困惑,因为你会看到下面的输出显示我期望的字符串,但是数组的内容似乎是更新引用而不是值?我糊涂了。我已将代码删除到以下内容。基本上我有一个未知数量的“球员”,还有更多的属性,然后我在这里展示。每个“玩家”都有“装备”,实际上总共有24件。
我在这里使用了一个数组,因为我希望能够在阵列中的同一个索引处比较不同玩家的设备。
public class Equipment
{
public int PropA { get; set; }
public int PropB { get; set; }
public Equipment ()
{
PropA = 0;
PropB = 0;
}
public Equipment (Equipment eq)
{
PropA = eq.PropA;
PropB = eq.PropB;
}
}
public class Player
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Equipment[] Equip = new Equipment[2];
public Player ()
{
FirstName = "";
LastName = "";
for (int i=0; i<Equip.Length; i++)
{
this.Equip[i] = new Equipment();
}
}
public Player (Player p)
{
FirstName = p.FirstName;
LastName = p.LastName;
for (int i=0; i<p.Equip.Length; i++)
{
this.Equip[i] = p.Equip[i];
}
}
}
public void LoadPlayers()
{
Player tmpPlayer = new Player();
List<Player> PlayerList = new List<Player>();
tmpPlayer.FirstName = "One";
tmpPlayer.LastName = "Two";
tmpPlayer.Equip[0].PropA = 1;
tmpPlayer.Equip[0].PropB = 2;
tmpPlayer.Equip[1].PropA = 3;
tmpPlayer.Equip[1].PropB = 4;
PlayerList.Add(new Player(tmpPlayer));
tmpPlayer.FirstName = "Three";
tmpPlayer.LastName = "Four";
tmpPlayer.Equip[0].PropA = 5;
tmpPlayer.Equip[0].PropB = 6;
tmpPlayer.Equip[1].PropA = 7;
tmpPlayer.Equip[1].PropB = 8;
PlayerList.Add(new Player(tmpPlayer));
foreach (Player p in PlayerList)
{
Console.WriteLine(p.FirstName);
Console.WriteLine(p.LastName);
Console.WriteLine(p.Equip[0].PropA.ToString());
Console.WriteLine(p.Equip[0].PropB.ToString());
Console.WriteLine(p.Equip[1].PropA.ToString());
Console.WriteLine(p.Equip[1].PropB.ToString());
}
}
这是我得到的输出:
一 二 五 6 7 8 三 四 五 6 7 8
这是我预期的输出:
一 二 1 2 3 4 三 四 五 6 7 8
除了指出我的错误之外,还有一种明显更好的方法来实现我的目标吗?
提前感谢您,我感谢您的帮助!
答案 0 :(得分:1)
您需要更改
public Equipment[] Equip = new Equipment[1];
要public Equipment[] Equip = new Equipment[2];
,否则您将获得IndexOutOfRangeException
。
在你的LoadPlayers
方法中,你正在修改Player
的同一个实例,而不是创建一个新的播放器。所以你得到相同的输出,因为你只有一个实例。创建一个新实例然后添加它列在你的名单上。
Player tmpPlayer = new Player();
/* set the properties */
PlayerList.Add(new Player(tmpPlayer));
tmpPlayer = new Player();
/* set the properties */
PlayerList.Add(new Player(tmpPlayer));
你应该得到你期望的输出。
答案 1 :(得分:1)
问题是您只设置了对象tmpPlayer的一个实例,并在您第二次尝试设置其参数时覆盖了对象中的值。
您可以尝试而不是制作一个对象,然后在整个时间内更改它并遇到内存引用问题,每次都可以将新对象放入数组中,并在添加对象时设置其属性。你应该能够像这样实现它
PlayerList.Add(new Player()
{
FirstName = "One";
LastName = "Two";
Equip[0].PropA = 1;
Equip[0].PropB = 2;
Equip[1].PropA = 3;
Equip[1].PropB = 4;
});
PlayerList.Add(new Player()
{
FirstName = "Three";
LastName = "Four";
Equip[0].PropA = 5;
Equip[0].PropB = 6;
Equip[1].PropA = 7;
Equip[1].PropB = 8;
});
有了这个,每个对象都应该是唯一的,希望你能得到你想要的输出。
答案 2 :(得分:1)
问题是您的复制构造函数public Player (Player p)
会将复制的播放器的设备分配给新播放器。由于您使用此构造函数创建实际放入列表中的两个玩家,因此他们的设备都指的是原始玩家tmpPlayer
的设备。
您可以通过让复制构造函数执行设备的副本来解决此问题:
public Player (Player p)
{
FirstName = p.FirstName;
LastName = p.LastName;
for (int i=0; i<p.Equip.Length; i++)
{
this.Equip[i] = new Equipement(p.Equip[i]);
}
}