列表元素相互依赖
List elements are dependant from each other
出于某种原因,我的列表 (Maps = new List<CollisionTiles>[]
) 中的元素相互依赖。此列表包含有关我的游戏中的碰撞图块的信息。问题是,当我将 Map
列表中的列表元素设置为 Maps[Something]
时,Maps
列表也在改变,每当我在分配后对 Map
做任何事情时。
if (mapClass.Maps[3].Count != 0)
{
mapClass.ClearMap(); // CollisionTiles.Clear(); BackGroundTiles.Clear();
mapClass.CollisionTiles = mapClass.Maps[3];
mapClass.BackgroudTiles = mapClass.SpriteMaps[3];
}
if (mapClass.Maps[3].Count == 0)
{
mapClass.GenerateCustomMap(64, 10, 8, 3, false);
}
从您发布的代码中很难判断,但根据您的描述,您可能正在将 "reference" 复制到集合中,而您打算复制集合本身。
例如,假设有一个名为 a
的列表,您尝试创建另一个名为 b
的列表,如下所示:
var a = new List<string>();
var b = a;
上面的代码实际做的是使 a
和 b
成为 相同列表 的 "reference"。
换句话说,如果你随后做了这样的事情:
b.Add("item");
现在,名为 a
和 b
的 "lists" 都将包含相同的项目。那是因为它们实际上不是不同的列表,它们是具有两个 "pointers".
的相同列表
有几种不同的方法可以在 C# 中正确复制列表。一种方法是像这样将列表传递给构造函数:
var a = new List<string>();
a.Add("item");
var b = new List<string>(a);
这将为您提供两个单独的列表,其中都有一个项目。但是,现在当您修改这些列表中的任何一个时,它们不会一起更改。
上述代码的流行(更现代)替代方法可以通过 using System.Linq
命名空间完成。
var a = new List<string>();
a.Add("item");
var b = a.ToList();
希望对您有所帮助。
您正在将 mapClass.CollisionTiles
设置为 引用 原始 List
。
因此,对 mapClass.CollisionTiles
的任何修改也会更改原始 List
。 BackgroundTiles
.
也是如此
要更正此问题,请在将对象分配给 mapClass
时创建新的 List
对象:
if (mapClass.Maps[3].Count != 0)
{
mapClass.ClearMap(); // CollisionTiles.Clear(); BackGroundTiles.Clear();
mapClass.CollisionTiles = new List<CollisionTiles>(mapClass.Maps[3]);
mapClass.BackgroudTiles = new List<BackgroudTiles>(mapClass.SpriteMaps[3]);
}
else // this is the only other option from the above if
{
mapClass.GenerateCustomMap(64, 10, 8, 3, false);
}
请注意,我留下了 BackgroudTiles
的拼写错误,请根据需要更正。
出于某种原因,我的列表 (Maps = new List<CollisionTiles>[]
) 中的元素相互依赖。此列表包含有关我的游戏中的碰撞图块的信息。问题是,当我将 Map
列表中的列表元素设置为 Maps[Something]
时,Maps
列表也在改变,每当我在分配后对 Map
做任何事情时。
if (mapClass.Maps[3].Count != 0)
{
mapClass.ClearMap(); // CollisionTiles.Clear(); BackGroundTiles.Clear();
mapClass.CollisionTiles = mapClass.Maps[3];
mapClass.BackgroudTiles = mapClass.SpriteMaps[3];
}
if (mapClass.Maps[3].Count == 0)
{
mapClass.GenerateCustomMap(64, 10, 8, 3, false);
}
从您发布的代码中很难判断,但根据您的描述,您可能正在将 "reference" 复制到集合中,而您打算复制集合本身。
例如,假设有一个名为 a
的列表,您尝试创建另一个名为 b
的列表,如下所示:
var a = new List<string>();
var b = a;
上面的代码实际做的是使 a
和 b
成为 相同列表 的 "reference"。
换句话说,如果你随后做了这样的事情:
b.Add("item");
现在,名为 a
和 b
的 "lists" 都将包含相同的项目。那是因为它们实际上不是不同的列表,它们是具有两个 "pointers".
有几种不同的方法可以在 C# 中正确复制列表。一种方法是像这样将列表传递给构造函数:
var a = new List<string>();
a.Add("item");
var b = new List<string>(a);
这将为您提供两个单独的列表,其中都有一个项目。但是,现在当您修改这些列表中的任何一个时,它们不会一起更改。
上述代码的流行(更现代)替代方法可以通过 using System.Linq
命名空间完成。
var a = new List<string>();
a.Add("item");
var b = a.ToList();
希望对您有所帮助。
您正在将 mapClass.CollisionTiles
设置为 引用 原始 List
。
因此,对 mapClass.CollisionTiles
的任何修改也会更改原始 List
。 BackgroundTiles
.
要更正此问题,请在将对象分配给 mapClass
时创建新的 List
对象:
if (mapClass.Maps[3].Count != 0)
{
mapClass.ClearMap(); // CollisionTiles.Clear(); BackGroundTiles.Clear();
mapClass.CollisionTiles = new List<CollisionTiles>(mapClass.Maps[3]);
mapClass.BackgroudTiles = new List<BackgroudTiles>(mapClass.SpriteMaps[3]);
}
else // this is the only other option from the above if
{
mapClass.GenerateCustomMap(64, 10, 8, 3, false);
}
请注意,我留下了 BackgroudTiles
的拼写错误,请根据需要更正。