Find()vs. Where()。FirstOrDefault()

时间:2012-02-17 20:35:28

标签: c# linq linq-to-objects

我经常看到有人使用Where.FirstOrDefault()进行搜索并抓住第一个元素。为什么不使用Find()?对方是否有优势?我无法区分。

namespace LinqFindVsWhere
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> list = new List<string>();
            list.AddRange(new string[]
            {
                "item1",
                "item2",
                "item3",
                "item4"
            });

            string item2 = list.Find(x => x == "item2");
            Console.WriteLine(item2 == null ? "not found" : "found");
            string item3 = list.Where(x => x == "item3").FirstOrDefault();
            Console.WriteLine(item3 == null ? "not found" : "found");
            Console.ReadKey();
        }
    }
}

7 个答案:

答案 0 :(得分:174)

Find上的IEnumerable<T>方法在哪里? (修辞问题。)

WhereFirstOrDefault方法适用于多种序列,包括List<T>T[]Collection<T>等。任何实现{ {1}}可以使用这些方法。 IEnumerable<T>仅适用于Find。通常更适用的方法更加可重复使用并产生更大的影响。

  

我想我的下一个问题是他们为什么要添加查找。这是一个很好的提示。我唯一能想到的是FirstOrDefault可以返回除null之外的其他默认值。否则它似乎是一个毫无意义的添加

List<T>上的{p> Find早于其他方法。 List<T>在.NET 2.0中添加了泛型,List<T>是该类API的一部分。 FindWhere被添加为FirstOrDefault与Linq的扩展方法,Linq是后来的.NET版本。我不能肯定地说,如果Linq存在于2.0版本中,IEnumerable<T>将永远不会被添加,但可以说早期.NET版本中的许多其他功能的情况可能会在以后被淘汰或冗余版本。

答案 1 :(得分:42)

我今天刚刚发现,在80K对象列表上进行了一些测试,发现Find()比使用Where FirstOrDefault()快了1000%。直到每个人之前和之后测试一个计时器我都不知道。有时它是同一时间,否则它更快。

答案 2 :(得分:27)

FindList<T> Where().FirstOrDefault(),而IEnumerable<T>适用于所有{{1}}。

答案 3 :(得分:25)

如果数据来源是实体框架,则会有一个非常重要的区别:Find会找到尚未保留的“已添加”状态的实体,但Where不会。这是设计的。

答案 4 :(得分:1)

哇,我今天才在Youtube上观看MicrosofToolbox的EF教程。 他确实说过要在查询中使用Find()和FirstOrDefault(condition),并且Find()将搜索您对该对象执行过某些操作的数据(添加或编辑或删除-但尚未保存到数据库中),而FirstOrDefault仅会寻找已经保存的内容

答案 5 :(得分:0)

除了安东尼回答 Where()遍历所有记录,然后返回结果,而Find()如果谓词与给定谓词匹配,则无需遍历所有记录。

所以说您拥有具有idname属性的Test类的列表。

 List<Test> tests = new List<Test>();
 tests.Add(new Test() { Id = 1, Name = "name1" });
 tests.Add(new Test() { Id = 2, Name = "name2" });
 tests.Add(new Test() { Id = 3, Name = "name3" });
 tests.Add(new Test() { Id = 4, Name = "name2" }); 
 var r = tests.Find(p => p.Name == "name2");
 Console.WriteLine(r.Id);

将给出2的输出,并且只有 2 次访问查找需要给出结果,但是如果您使用Where().FirstOrDefault(),我们将访问所有记录,然后得到结果。

因此,当您知道只希望集合Find()中的记录的第一个结果比Where().FirtorDefault();更为合适

答案 6 :(得分:0)

Find()FirstOrDefault()的IEnumerable等效项。您不应该将两个.Where()与.FirstOrDefault()链接在一起,因为.Where()将遍历整个数组,然后将遍历该列表以查找第一项。通过将搜索谓词置于FirstOrDefault()方法中,可以节省大量时间。

此外,我建议您阅读与此线程相关的链接问题,以了解更多有关在特定场景Performance of Find() vs. FirstOrDefault()中使用.Find()的更好性能的信息