为什么 IEnumerable 没有提供 ForEach ?
咨詢區
Cameron MacFarland:
為什么 IEnumerable 接口沒有 ForEach 擴展方法?我觀察到能獲取 ForEach 方法的類是 List<>,有誰知道這么設計的原因嗎,是為了性能?
回答區
aku:
ForEach 方法其實在 Linq 之前就已經存在了,如果這時候在 IEnumerable 上添加 ForEach 擴展方法的話會出現什么結果呢?大家應該知道擴展方法的優先級是低于同名的非擴展方法,這就意味著 IEnumerable 下的 ForEach 永遠得不到調用。
如果你真的想要這個功能,可以自己實現一個。
public?static?void?ForEach<T>(this?IEnumerable<T>?source,?Action<T>?action) {foreach?(T?element?in?source)?action(element); }leppie:
大多數 Linq 擴展方法都會返回 result,但 ForEach 這種不返回的擴展方法并不適合在這種模式中。
Martijn:
你可以使用鏈式延遲的 Select 來替換 ForEach, 比如下面這樣。
IEnumerable<string>?people?=?new?List<string>(){"alica",?"bob",?"john",?"pete"}; people.Select(p?=>?{?Console.WriteLine(p);?return?p;?});如果要立即執行的話,可以再調用 Count(),據我所知這是觸發迭代最小代價的方法,當然你可以調用你需要的立即執行方法。
不過我倒希望下面的擴展方法被引入到標準類庫中。
static?IEnumerable<T>?WithLazySideEffect(this?IEnumerable<T>?src,?Action<T>?action)?{return?src.Select(i?=>?{?action(i);?return?i;?}?); }上面的代碼等價于 foreach,不過是鏈式延遲的。
點評區
Linq 不提供 ForEach 擴展方法,我感覺是設計者故意為之的,Linq 的一個強大特性在于可鏈式,可延遲,它和 ForEach 中間還差了一個 ToList,也許手工 ToList 可以讓代碼意圖更明顯吧,比如:
static?void?Main(string[]?args){IEnumerable<Person>?list?=?new?List<Person>();list.Where(v?=>?v.Name?==?"xxx").ToList().ForEach(m?=>?Console.WriteLine(m.Name));}當然你不認同這種理念也沒關系,很多的 Linq 擴展庫也不認同,它們就直接提供了 ForEach,比如:MoreLinq ? https://github.com/morelinq/
原文鏈接:https://stackoverflow.com/questions/101265/why-is-there-no-foreach-extension-method-on-ienumerable#101303
總結
以上是生活随笔為你收集整理的为什么 IEnumerable 没有提供 ForEach ?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#使用iTextSharp操作PDF文
- 下一篇: 在 CAP 中使用 AOP ( Cast