我不认为我正在修改这个系列

时间:2012-01-30 22:05:47

标签: c# list object collections

代码:

    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 正在循环的内容,因此我感到困惑。有人可以向我解释一下吗?感谢。

3 个答案:

答案 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);
    }
}