NET问答: Find() 和 Where().FirstOrDefault() 该如何选择 ?
咨詢區
KingOfHypocrites:
我經常看到別人用 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();}} }回答區
Abhinav Galodha:
在 IEnumerable<T> 上你能找到 Find 嗎?
Where 和 FirstOrDefault 可用在多種序列集合上,包括:List<T>, T[], Collection<T> 等等,任何實現了 IEnumerable<T> 的集合都可以使用這兩個方法。
Find 僅僅是在 List<T> 上可用。
M Muneeb Ijaz:
它們兩者的區別在于,Where() 方法會遍歷所有的記錄然后再返回結果,而 Find() 方法則不會遍歷所有記錄,它只需遇到指定的 predicate 滿足后即可返回。
我用 List<Test> 來做一個演示。
class?Program{static?void?Main(string[]?args){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);}}class?Test{public?int?Id?{?get;?set;?}public?string?Name?{?get;?set;?}}為了能找到圖中的 2,Find 方法只需訪問兩次記錄即可, 而 Where().FirstOrDefault() 則需訪問 4 次,也就是全盤遍歷。
點評區
匯總兩位大佬的答案就是:易用 和 性能 絕對是成反比的,比如你知道的 ADO.NET 和 EntityFramework, 又或者是 匯編 和 C# ...
其次要想深究,我覺得可以多用用 ILSpy 去挖挖源碼。
//?System.Collections.Generic.List<T> public?T?Find(Predicate<T>?match) {if?(match?==?null){ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);}for?(int?i?=?0;?i?<?_size;?i++){if?(match(_items[i])){return?_items[i];}}return?default(T); }//?System.Linq.Enumerable public?static?TSource?FirstOrDefault<TSource>(this?IEnumerable<TSource>?source) {if?(source?==?null){throw?Error.ArgumentNull("source");}IList<TSource>?list?=?source?as?IList<TSource>;if?(list?!=?null){if?(list.Count?>?0){return?list[0];}}else{using?(IEnumerator<TSource>?enumerator?=?source.GetEnumerator()){if?(enumerator.MoveNext()){return?enumerator.Current;}}}return?default(TSource); }總結
以上是生活随笔為你收集整理的NET问答: Find() 和 Where().FirstOrDefault() 该如何选择 ?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 又一起.NET程序挂死, 用 Windb
- 下一篇: 一文说通C#的属性Attribute