c# - IEnumerable 中的项目不等于 List 中的项目

标签 c# linq list lambda ienumerable

我只是想不通为什么找不到我筛选列表中的项目。我已经简化了这个例子来展示它。我有一个类项目...

public class Item
{
    public Item(string name)
    {
        Name = name;
    }

    public string Name
    {
        get; set;
    }

    public override string ToString()
    {
        return Name;
    }
}

...和一个“项目”类,它应该过滤项目并检查第一个项目是否仍在列表中...

public class Items
{
    private IEnumerable<Item> _items;

    public Items(IEnumerable<Item> items)
    {
        _items = items;
    }

    public List<Item> Filter(string word)
    {
        var ret = new List<Item>(_items.Where(x => x.Name.Contains(word)));

        Console.WriteLine("found: " + ret.Contains(_items.First()));
        // found: false

        return ret;
    }
}

执行代码如下所示:

static void Main(string[] args)
{
    string[] itemNames = new string[] { "a", "b", "c" };

    Items list = new Items(itemNames.Select(x => new Item(x)));
    list.Filter("a");

    Console.ReadLine();
}

现在,如果我执行该程序,Console.WriteLine 输出找不到该项目。但是为什么?

如果我将构造函数中的第一行更改为

 _items = items.ToList()

然后,它就可以找到它。如果我撤消该行并稍后在 Filter 方法中调用 ToList(),它也找不到该项目?!

public class Items
{
    private IEnumerable<Item> _items;

    public Items(IEnumerable<Item> items)
    {
        _items = items;
    }

    public List<Item> FilteredItems
    {
        get; set;
    }

    public List<Item> Filter(string word)
    {
        var ret = new List<Item>(_items.Where(x => x.Name.Contains(word)));

        _items = _items.ToList();
        Console.WriteLine("found: " + ret.Contains(_items.First()));
        // found: false

        return ret;
    }
}

为什么执行 lambda 表达式的时间和地点不同,为什么找不到该项目?我不明白!

最佳答案

原因是延迟执行

您将 _items 字段初始化为

itemNames.Select(x => new Item(x));

这是一个查询,而不是该查询的答案。每次迭代 _items 时,都会执行此查询。

所以在 Filter 方法的这一行中:

var ret = new List<Item>(_items.Where(x => x.Name.Contains(word)));

枚举源数组并为每个字符串创建一个 new Item(x)。这些项目存储在您的列表 ret 中。

当您之后调用 Contains(_items.First()) 时,First() 再次 执行查询_items 中,为每个源字符串创建 Item 实例。

由于 ItemEquals 方法可能未被覆盖并执行简单的引用相等性检查,所以从第二次迭代返回的第一个 Item Item 的实例与列表中的实例不同。

关于c# - IEnumerable 中的项目不等于 List 中的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41266178/

相关文章:

c# - 目标 BeforeBuild 在 csproj 中不起作用

python - 将字符串放入 Python 列表中

c - 函数只能运行一次 - C

c# - 如何在没有 JavaScript 的情况下验证表单?

c# - 如何使 C# 构造函数语法更像 pythonic?

c# - Dapper 参数不起作用

c# - 如何动态指定 Linq OrderBy 参数?

c# - Linq 不包含动态查询

C# LINQ - 将类的所有属性与同一类的不同实例进行比较的 Select 语句?

Python:根据文件内容构建字典