C#为什么Except和Where Enumerable给出了这个奇怪的结果?

Loo*_*op9 5 c# ienumerator enumerator

我一直在调试这个生产错误,我迫切需要帮助,这对我来说也很有意思.

我简化了代码逻辑并为调试添加了一些打印输出:

int[] a = { 2,2,2 };
var b = a.Where(x => x==2);

for(int i = 0; i < 3; i++)
{
    var c = b.Where(x => x==i);

    Console.WriteLine("iter {0} before - B Count: {1}, C Count: {2}", i, b.Count(), c.Count());

    if (c.Count() != b.Count())
        b = b.Except(c);

    Console.WriteLine("iter {0} after - B Count: {1}, C Count: {2}", i, b.Count(), c.Count());
}

Console.WriteLine("After Loop: B Count: {0}", b.Count());
Run Code Online (Sandbox Code Playgroud)

有趣的是(奇怪),输出是:

iter 0 before - B Count: 3, C Count: 0
iter 0 after - B Count: 1, C Count: 0
iter 1 before - B Count: 1, C Count: 0
iter 1 after - B Count: 1, C Count: 0
iter 2 before - B Count: 0, C Count: 0
iter 2 after - B Count: 0, C Count: 0
After Loop: B Count: 1
Run Code Online (Sandbox Code Playgroud)

问题1:

为何选择b.Count() == 0"之前的2".唯一的事情发生在"iter 1 after和iter 2 before"之间

var c = b.Where(x => x==i);
Run Code Online (Sandbox Code Playgroud)

为什么这个代码会改变b?

问题2:

为什么b.Count()在循环结束后变回1?

我非常感谢大家的帮助,指导我解决这个问题,谢谢!

Tim*_*ter 0

Enumerable.Except通过使用默认的相等比较器来比较值,生成两个序列的集合差。集合不包含重复项。

这就是为什么该序列在 后仅包含一个 2 Except

int[] onlyOneTwo = new[]{ 2,2,2 }.Except(Enumerable.Empty<int>()).ToArray();
Run Code Online (Sandbox Code Playgroud)

因此,空序列不会删除任何内容,但Except使用 set