关于c#:Find()vs. Where()。FirstOrDefault()

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

我经常看到人们使用Where.FirstOrDefault()进行搜索并获取第一个元素。为什么不直接使用Find()?有什么优势吗?我看不出有什么不同。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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();
        }
    }
}


IEnumerable上的Find方法在哪里?(反问句)

WhereFirstOrDefault方法适用于多种序列,包括ListT[]Collection等,任何实现IEnumerable的序列都可以使用这些方法。Find仅适用于List。通常更适用的方法,然后更可重用并具有更大的影响。

I guess my next question would be why did they add the find at all. That is a good tip. The only thing I can think of is that the FirstOrDefault could return a different default value other than null. Otherwise it just seems like a pointless addition

List上的Find比其它方法早。List在.NET 2.0中添加了泛型,Find是该类API的一部分。添加了WhereFirstOrDefault作为带有linq的IEnumerable的扩展方法,linq是较新的.NET版本。我不能肯定地说,如果linq与2.0版本一起存在,那么Find将永远不会被添加,但可以肯定的是,早期.NET版本中的许多其他功能已经被后期版本废弃或冗余。


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


Find只在List中执行,而Where().FirstOrDefault()与所有IEnumerable一起工作。


如果数据源是实体框架,则有一个非常重要的区别:Find将发现处于"添加"状态的实体尚未持久化,但Where将不会持久化。这是按设计的。


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

假设您有一个具有idname属性的测试类列表。

1
2
3
4
5
6
7
 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();更合适。