假设我有以下代码:
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()函数按值传递,对吗?那么这是怎么发生的呢?
注意:我知道有一些程序化的替代品,我正在做的事情,我已经采用了一个。我只是好奇为什么会这样。
答案 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描述的路径:通过分离两个集合的引用依赖性。