2010-08-27 70 views
12

剛纔發現偶然,Add(T)定義在ICollection<T>中,而不是IEnumerable<T>。 Enumerable.cs中的擴展方法不包含Add(T),我認爲這很奇怪。由於對象是可枚舉的,它必須「看起來像」一組項目。誰能告訴我爲什麼?爲什麼IEnumerable <T>實現Add(T)?

+0

當初的IEnumerable''需要'來實現Add',會有更多的問題其他方式:*爲什麼'IEnumerable '有'Add' *。它的方式是非常有用的:) – nawfal 2014-06-08 08:17:59

回答

45

一個IEnumerable<T>只是一個元素序列;將其視爲僅前向遊標。因爲很多這些序列都是從數據庫中生成值,數據流或記錄集,所以Add項對它們沒有任何意義。

+9

+1使用單詞*序列*,因爲IEnumerable恰好是,而不是某種集合。 – OregonGhost 2010-08-27 08:14:22

+5

downvoters可以解釋他們爲什麼downvoted? – Steven 2012-04-18 18:10:05

11

IEnumerable是供閱讀,而不是寫作。

2

顧名思義,你可以通過IEnumerable枚舉(循環),就是這樣。 當你想添加一些東西時,它不會只是一個枚舉,因爲它有額外的功能。例如,一個數組是一個IEnumerable,但是一個數組的長度是固定的,所以你不能向它添加新的項目。我們可以使用IEnumerable作爲所有類型集合的基礎(甚至只讀集合 - 顯然沒有Add()方法)。 您將添加到這種「基礎接口」的功能越多,它就越具體。

10

一個枚舉就是這樣 - 你可以枚舉並發現所有項目。這並不意味着你可以添加到它。

能夠枚舉對於許多類型的對象是通用的。例如,它由數組和集合共享。但是你不能'添加'到一個數組而不會搞亂它的結構 - 而一個Collection是專門構建的添加和刪除。

然而,從技術上講,你可以通過使用Concat<>來添加一個枚舉值,但是所有這些都會創建一個從枚舉值枚舉到下一值枚舉值的枚舉值 - 給出單個連續集的錯覺。

+0

+1表示可選的Concat。 – Emile 2010-08-27 12:02:47

2

名稱說明了一切。 IEnumerable僅用於枚舉項目。 ICollection是項目的實際集合,因此支持Add方法。

3

每個ICollection應該是IEnumerable(我認爲,和.NET框架團隊似乎同意我;-)),但其他方式並不總是有意義的。在這個世界中存在一個「類似集合的對象」的層次結構,並且假定一個可枚舉集合是一個可以添加項目的集合,在該層次結構中不成立。

示例:原色名稱列表將爲IEnumerable返回"Red","Blue""Green"。這也就沒有什麼邏輯意義的是能夠在充滿這樣的「收藏」做一個primaryColors.Add("Bright Purple")

...whatever... 
{ 
    ... 
    var primaryColors = EnumeratePrimaryColors(); 
    ... 
} 

private static IEnumerable<string> EnumeratePrimaryColors() { 
    yield return "Red"; 
    yield return "Blue"; 
    yield return "Green"; 
} 
+0

'ICollection'繼承自'IEnumerable'並且'ICollection '繼承自'IEnumerable '(它繼承自IEnumerable')。換句話說,你是對的:每個'ICollection'都是'IEnumerable'。 – Steven 2010-08-27 08:21:11

+0

@Steven:我知道...... – peSHIr 2010-08-27 08:24:34

相關問題