我经常看到有人使用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();
}
}
}
答案 0 :(得分:174)
Find
上的IEnumerable<T>
方法在哪里? (修辞问题。)
Where
和FirstOrDefault
方法适用于多种序列,包括List<T>
,T[]
,Collection<T>
等。任何实现{ {1}}可以使用这些方法。 IEnumerable<T>
仅适用于Find
。通常更适用的方法更加可重复使用并产生更大的影响。
我想我的下一个问题是他们为什么要添加查找。这是一个很好的提示。我唯一能想到的是FirstOrDefault可以返回除null之外的其他默认值。否则它似乎是一个毫无意义的添加
List<T>
上的{p> Find
早于其他方法。 List<T>
在.NET 2.0中添加了泛型,List<T>
是该类API的一部分。 Find
和Where
被添加为FirstOrDefault
与Linq的扩展方法,Linq是后来的.NET版本。我不能肯定地说,如果Linq存在于2.0版本中,IEnumerable<T>
将永远不会被添加,但可以说早期.NET版本中的许多其他功能的情况可能会在以后被淘汰或冗余版本。
答案 1 :(得分:42)
我今天刚刚发现,在80K对象列表上进行了一些测试,发现Find()
比使用Where
FirstOrDefault()
快了1000%。直到每个人之前和之后测试一个计时器我都不知道。有时它是同一时间,否则它更快。
答案 2 :(得分:27)
Find
仅List<T>
Where().FirstOrDefault()
,而IEnumerable<T>
适用于所有{{1}}。
答案 3 :(得分:25)
如果数据来源是实体框架,则会有一个非常重要的区别:Find
会找到尚未保留的“已添加”状态的实体,但Where
不会。这是设计的。
答案 4 :(得分:1)
哇,我今天才在Youtube上观看MicrosofToolbox的EF教程。 他确实说过要在查询中使用Find()和FirstOrDefault(condition),并且Find()将搜索您对该对象执行过某些操作的数据(添加或编辑或删除-但尚未保存到数据库中),而FirstOrDefault仅会寻找已经保存的内容
答案 5 :(得分:0)
除了安东尼回答
Where()
遍历所有记录,然后返回结果,而Find()
如果谓词与给定谓词匹配,则无需遍历所有记录。
所以说您拥有具有id
和name
属性的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()
的更好性能的信息