回答
IEnumerable僅提供最小的「可迭代」功能。你可以遍歷序列,但這就是它。這有缺點 - 例如,使用IEnumerable對元素進行計數或獲取第n個元素的效率非常低 - 但它也有優勢 - 例如,IEnumerable可能是無窮無盡的序列,就像素數序列一樣。
數組是固定大小的隨機訪問集合(即,您可以對其進行索引)。
列表是一個可變大小的集合(即可以添加和刪除元素)和隨機訪問。
IList的是抽象列表功能(計數,添加,刪除,索引訪問)從各種具體類,如List,的BindingList,的ObservableCollection等
IEnumerable和IList是interfaces。數組和列表是類。數組實現IEnumerable。 List實現了擴展IEnumerable的IList。
編輯:正如itowlson在評論中提到的,Array也實現了IList。
IEnumerable是一個接口,允許迭代項目集合(例如通過foreach關鍵字)。
數組是.NET的本質。它包含相同類型的項目,但它的大小是固定的。一旦你創建了一個包含x個元素的數組,它不能增長或縮小。
IList爲列表定義了接口,並且還實現了IEnumerable。
List實現IList接口;它是一個具體類型的列表。
.NET列表和數組之間的區別在於列表可以添加元素 - 它們的大小足以容納所有必需的項目。該列表在內部將其存儲在一個數組中,並且當數組不足夠大以容納所有元素時,將創建一個新數組並將其複製。
IList &數組都實現IEnumerable。這就是接口的工作方式 - 類實現契約並以類似的方式運行,並且可以被視爲類似的結果(您知道該類實現IEnumerable,您不需要知道這些是什麼意思)。我建議你閱讀接口等等。
IEnumerable
遠離的接口是通用的接口,其被許多類使用,例如Array
,List
和String
,以便讓某人迭代集合。基本上,這是驅動foreach
聲明的原因。
IList
通常是如何將List
類型的變量暴露給最終用戶。該接口允許隨機訪問基礎集合。IEnumerable集合的
代是懶惰。 實施例:
public IEnumerable<int> GetTwoInts()
{
yield return 1;
yield return 2;
}
public void Something()
{
var twoInts = GetTwoInts();
}
在該方法的東西調用GetTwoInts()實際上不會導致方法GetTwoInts由於枚舉從未遍歷被執行。
這是一個古老的職位,但仍想回答的。 IEnumerable是一種行爲,而Array是一種數據結構(固定大小的元素的連續集合,便於按索引訪問元素)。 當一個數組實現IEnumerable時,它應該也描述IEnumerable固有屬性(促進對集合的迭代)。
爲了配合其他的答案,注意執行foreach語句時,有IList<T>
和List<T>
之間的性能差異。
這是因爲通過List<T>.GetEnumerator
返回的迭代器對象是一個值類型而由IList<T>.GetEnumerator
返回的一個是引用類型,因此需要的存儲器分配(見Enumerator of value type of list in c#)。
在我看來,IList<T>
是不是一個很好的接口反正。例如撥打Add
可以拋出(見Why array implements IList?)。如果你需要封裝,你最好使用IEnumerable<T>
或IReadOnlyList<T>
。
數組也實現IList。 – itowlson 2009-04-19 03:04:23
我也不是!但是如果你開始在數組上調用IList.RemoveAt會發生什麼? – 2009-04-19 03:13:00
它引發NotSupportedException。 (注IList.RemoveAt和類似IList的方法是在陣列明確執行,以使他們不正常的陣列參考現身!) – itowlson 2009-04-19 03:19:50