如何从一个列表中删除从这些foreach循环中的另一个列表中删除?

时间:2012-08-31 18:30:03

标签: c#

假设我有以下代码:

List<Category> categories = getCategories();
List<Category> unusedCategories = categories;
    foreach (var category in categories)
        foreach (var imageCategory in image.Categories)
            if (category.CategoryID == imageCategory.CategoryID)
                unusedCategories.Remove(category);

我收到的错误是集合在循环期间被修改了。果然,当我逐步调试调试器时,如果使用了删除(类别),“类别”列表就比以前更短了一个元素!为什么从“unusedCategories”中删除会影响“类别”?它们应该是两个不同的列表,而不是引用相同的东西。并且.Remove()函数按值传递,对吗?那么这是怎么发生的呢?

注意:我知道有一些程序化的替代品,我正在做的事情,我已经采用了一个。我只是好奇为什么会这样。

2 个答案:

答案 0 :(得分:9)

  

它们应该是两个不同的列表,而不是引用相同的东西

事实并非如此。当您将categories分配给unusedCategories时,您将通过引用分配

如果您需要副本,则需要明确复制该列表:

List<Category> unusedCategories = new List<Category>(categories);

对于更有效的替代方案,您可以考虑以下内容:

HashSet<int> usedCategoryIds = new HashSet<int>(image.Categories.Select(c => c.CategoryID));

List<Category> categories = getCategories();
List<Cagegory> unusedCategories = categories.Where(c => !usedCategoryIds.Contains(c => c.CategoryID)).ToList();

答案 1 :(得分:0)

您可以使用LINQ执行此操作,例如:

var removables = from category in categories
                        join imageCategory in image.Categories 
                              on category.CategoryID equals 
                                 imageCategory.CategoryID  select category;

并在删除后

 unusedCategories.RemoveAll(removables );

或者您可以使用for循环以避免出现异常。

或遵循@Reed描述的路径:通过分离两个集合的引用依赖性。