使用Where和项目引用排除项目并不总是有效

时间:2015-09-22 21:55:33

标签: c# linq

我的代码中有一个由这些行引起的错误:

var itemToExclude = _myList.First();
var nextList = _myList.Where(i => i != itemToExclude);

itemToExclude中仍然存在nextList。 我使用Skip(1)而不是第二行来解决它,但是什么可能导致原始代码不起作用?

使用yield return的函数可能与它有关。

itemsToExclude是一个具有与

类似的只读属性的类
class RemainingItems
{
    private readonly IEnumerable<MyObject> _myObjects;
    public IEnumerable<MyObject> MyObjects { get { return _myObjects; } }

    private readonly int _remaining;
    public int Remaining { get { return _remaining; } }

    public RemainingItems(IEnumerable<MyObject> myObjects, int remaining)
    {
        _myObjects = myObjects;
        _remaining = remaining;
    }
}

1 个答案:

答案 0 :(得分:3)

因为myList由yield-method提供,所以每次遍历列表时都会重新创建项目。如果你不注意,它会在每次迭代时创建新对象:

  1. 第一次迭代将由_myList.First()
  2. 启动
  3. 第二次迭代将由_myList.Where(...)
  4. 启动

    然后将对象与!=进行比较以获得不等式,当两个引用都指向同一个对象时(仅忽略对象的实际内容),它仅计算为false。如上所述,yield-method可能会在每次迭代时创建新对象,因此!=将始终为真。

    有几种可能的解决方案:

    • 使用.Skip(1)
    • 在列表中使用.ToArray(),这样列表只会创建一次。
    • 使用正确实施的.Equals()方法

    每个解决方案都有其权衡。