C# 为什么使用“添加范围”将列表添加到另一个列表中会从第一个列表中删除元素?

C# 为什么使用“添加范围”将列表添加到另一个列表中会从第一个列表中删除元素?,c#,linq,ienumerable,addrange,C#,Linq,Ienumerable,Addrange,考虑以下示例: IEnumerable<Int32> groupsToAdd = new List<Int32>(); List<Int32> groups1 = new List<Int32>() { 1,2,3 }; List<Int32> groups2 = new List<Int32>() { 3,4,5 }; groupsToAdd = groups1.Where(g => false == group

考虑以下示例:

IEnumerable<Int32> groupsToAdd = new List<Int32>();

List<Int32> groups1 = new List<Int32>() { 1,2,3 };
List<Int32> groups2 = new List<Int32>() { 3,4,5 };

groupsToAdd = groups1.Where(g => false == groups2.Contains(g));

groups2.AddRange(groupsToAdd);

groupsToAdd.Dump();
IEnumerable groupsToAdd=new List();
列表组1=新列表(){1,2,3};
List groups2=新列表(){3,4,5};
groupsToAdd=groups1.Where(g=>false==groups2.Contains(g));
groups2.AddRange(groupsToAdd);
groupsToAdd.Dump();
调用
groupsToAdd.Dump()
时,列表现在为空。我查找了AddRange引用,它没有提到元素从列表中删除,但当我测试这段代码(在linqpad中)时,它以空结尾。为什么会这样

编辑:
为了澄清,我的意思是从
groupsToAdd
中删除元素,因为在
groups2之前。AddRange(groupsToAdd)
groupsToAdd填充了两个元素,这是因为IEnumerable。当您将groupsToAdd设置为
groups1.Where(g=>false==groups2.Contains(g))
的结果时,将延迟执行,这意味着直到AddRange()并再次在Dump()处运行查询。因为列表groups2现在包含元素,它们不再是原始查询的结果。

使用LINQ时,重要的是它会导致查询,而不是该查询的结果
groupsToAdd
不是一个项目列表,它只是一个查询的定义,可以在需要时获取一些项目

groupsToAdd
实际上不会迭代源序列(即
groups1
)或执行谓词检查(取决于
groups2
的状态),直到迭代为止

您迭代
groupsToAdd
两次。一次是调用
AddRange
,另一次是调用
Dump
。第二次迭代时,
group2
发生了变化,因此查询结果也发生了变化

如果希望避免这种延迟执行,则可以通过将代码修改为以下内容,立即具体化查询:

groupsToAdd = groups1.Where(g => false == groups2.Contains(g));
    .ToList();

这将及时评估查询,以便
groupsToAdd
将表示查询的结果,而不是查询本身。

一定有一些代码您没有显示给我们。上面的代码根本不会改变groups1。@itsme86不需要to@itsme86这是完整的代码,此代码本身将在linqpad和单元测试中“转储”空列表而是将查询具体化为
列表
。然后,由于不再有延迟执行,它的行为符合预期。@itsme86:“当调用groupsToAdd.Dump()时,列表现在为空”他认为
groupsToAdd
是一个不正确的列表。这应该是公认的答案。它清楚地解释了OP的问题。