IEnumerable vs List-使用什麼? 它們如何工做?

我對Enumerators和LINQ的工做方式有疑問。 考慮如下兩個簡單選擇: 數據庫

List<Animal> sel = (from animal in Animals 
                    join race in Species
                    on animal.SpeciesKey equals race.SpeciesKey
                    select animal).Distinct().ToList();

要麼 安全

IEnumerable<Animal> sel = (from animal in Animals 
                           join race in Species
                           on animal.SpeciesKey equals race.SpeciesKey
                           select animal).Distinct();

我更改了原始對象的名稱,以使其看起來像一個更通用的示例。 查詢自己不是那麼重要。 我想問的是: 性能

foreach (Animal animal in sel) { /*do stuff*/ }
  1. 我注意到,若是我使用IEnumerable ,則在調試和檢查「 sel」(在這種狀況下就是IEnumerable)時,它具備一些有趣的成員:「 inner」,「 outer」,「 innerKeySelector」和「 outerKeySelector」,這最後兩個彷佛是表明。 「內部」成員中沒有「動物」實例,而是「物種」實例,這對我來講很奇怪。 「外部」成員確實包含「動物」實例。 我假設這兩個表明肯定哪一個進出什麼? spa

  2. 我注意到,若是我使用「 Distinct」,則「 inner」包含6個項目(這是不正確的,由於只有2個是Distinct),可是「 outer」確實包含正確的值。 一樣,可能委託方法肯定了這一點,但這比我對IEnumerable的瞭解還多。 調試

  3. 最重要的是,這兩個選項中哪一個是性能最佳的? code

經過.ToList()邪惡列表轉換? 對象

仍是直接使用枚舉器? 圖片

若是能夠的話,也請解釋一下或拋出一些連接來解釋IEnumerable的用法。 內存


#1樓

沒有人提到一個關鍵的差別,具備諷刺意味的是,做爲一個重複的問題,有人回答了一個封閉的問題。 ci

IEnumerable是隻讀的,而List不是。

請參閱List和IEnumerable之間的實際區別


#2樓

有一篇很是不錯的文章由:Claudio Bernasconi的TechBlog撰寫: 什麼時候使用IEnumerable,ICollection,IList和List

這裏是有關方案和功能的一些基本知識:

在此處輸入圖片說明在此處輸入圖片說明


#3樓

要實現的最重要的事情是,使用Linq,查詢不會當即獲得評估。 它僅做爲在foreach中迭代生成的IEnumerable<T>一部分而運行-這就是全部奇怪的委託正在作的事情。

所以,第一個示例經過調用ToList並將查詢結果放入列表中來當即評估查詢。
第二個示例返回一個IEnumerable<T> ,其中包含稍後運行查詢所需的全部信息。

就性能而言,答案取決於它 。 若是您須要一次評估結果(例如,您要對稍後查詢的結構進行變異,或者您不但願IEnumerable<T>上的迭代花費很長時間),請使用列表。 不然使用IEnumerable<T> 。 默認狀況下,應該在第二個示例中使用按需評估,由於一般會使用較少的內存,除非有特殊緣由將結果存儲在列表中。


#4樓

若是您只想枚舉它們,請使用IEnumerable

可是請注意,更改要枚舉的原始集合是一項危險的操做-在這種狀況下,您將須要首先ToList 。 這將爲內存中的每一個元素建立一個新的list元素,枚舉IEnumerable ,所以若是僅枚舉一次,則性能會下降-但更安全,有時List方法很方便(例如,在隨機訪問中)。


#5樓

IEnumerable的優勢是延遲執行(一般使用數據庫)。 在您實際遍歷數據以前,查詢將不會執行。 這是一個查詢,直到須要它爲止(又稱延遲加載)。

若是您調用ToList,查詢將被執行,或者像我想說的那樣「物化」。

二者都有優勢和缺點。 若是調用ToList,則能夠消除執行查詢時的神祕性。 若是堅持使用IEnumerable,您將得到如下優點:該程序在實際須要以前不會執行任何工做。

相關文章
相關標籤/搜索