【问题标题】:How is removing from one list removing from another list in these foreach loops?在这些 foreach 循环中,如何从一个列表中删除?
【发布时间】:2012-09-01 02:35:27
【问题描述】:

假设我有以下代码:

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);

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

注意:我知道我在上面所做的事情有程序化的替代方案,而且我已经采用了一种。我只是好奇为什么会这样。

【问题讨论】:

标签: c#


【解决方案1】:

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

这不是真的。当您将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();

【讨论】:

  • 我明白了。为什么在这种情况下是引用赋值,而其他赋值(如 int y = x)是按值赋值?
  • @user1442605 因为List&lt;T&gt; 是一个引用类型(类)。 C# 中的任何class 都是引用类型,并且分配是通过引用进行的。任何struct(如Int32Double,或您创建的自定义结构)都是值类型,并按值分配。
  • 感谢您的解释。而且我一直想知道类和结构之间的区别是什么......我想我是很难学会的。
【解决方案2】:

您可以使用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 描述的路径:通过分离两个集合的引用依赖关系。

【讨论】:

  • 谢谢你,可惜我的公司让我瞄准 .net 2.0,所以我与 LINQ 调用的美妙脱节了。
  • @user1442605:这不是耻辱,而是商业战略。这种情况会发生,如果有一些财务上的便利,如果你能够向营销部门证明他们亏钱了,明天你将拥有 4.5 版本:)
猜你喜欢
  • 1970-01-01
  • 2020-01-24
  • 2013-11-24
  • 2018-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-14
相关资源
最近更新 更多