代码:
List<Item> Contents = ObjectHandler.player.Contents.ToList<Item>() //Was HashTable
List<int> IDS = new List<int>(); //Holds Item IDs for later counting
foreach (Item I in Contents)
{
IDS.Add(I.ID); // Add ID to IDS
}
List<Item> newContents = Contents;
foreach (Item I in Contents)
{
if (IDS.Contains(I.ID)) //Check if the ID has already been used in Contents
{
newContents.Remove(I); //Remove it
}
}
Contents = newContents;
此代码段应准备一份ID列表以供日后计算,并从项目列表中删除重复项。但是,只要 Contents 中存在某个项目,我就会收到 InvalidOperationException 。我相当肯定我没有修改 foreach 正在循环的内容,因此我感到困惑。有人可以向我解释一下吗?感谢。
答案 0 :(得分:7)
newContents = Contents;
您现在有两个指向同一集合的变量。
您可能希望通过编写new List<Item>(Contents)
来复制该集合。
答案 1 :(得分:0)
var Contents = ObjectHandler.player.Contents.ToList<Item>();
var IDs = new HashSet<int>();
var filtered = Contents.Where( i =>
{
bool result = !IDs.Contains(i.ID);
IDs.Add(i.ID);
return result;
}).ToList();
答案 2 :(得分:0)
虽然@SLaks指出了一种复制列表的好方法,并避免让两个对象指向同一个地方,但首先不需要两个列表。
如果您使用传统的for循环(而不是foreach)并向后计数,则可以从原始列表中删除项目,而不会抱怨任何内容。
下面的内容应该有效:
for (int i = Contents.Count - 1; i >= 0; i--)
{
if (IDS.Contains(Contents[i].ID)) //Check if the ID has already been used in Contents
{
Contents.RemoveAt(i);
}
}