我正在瀏覽IEnumerable和IEnumerator,但無法清楚地得到一點。如果我們有foreach,那麼爲什麼我們需要這兩個接口?有沒有我們必須使用接口的場景。如果是,那麼有人可以用一個例子來解釋。 歡迎任何建議和評論。 謝謝。IEnumerable,IEnumerator與foreach,何時使用什麼
22
A
回答
46
foreach
使用接口在許多情況下。如果你想實現那麼你需要這些接口,然後foreach
可以使用。 (雖然迭代器塊通常使這個實現任務非常簡單)。
但是,只是偶爾直接使用迭代器會很有用。一個很好的例子是當試圖「配對」兩個不同的序列時。例如,假設您收到兩個序列 - 名稱之一,年齡之一,並且您想將它們打印在一起。你可能會這樣寫:
static void PrintNamesAndAges(IEnumerable<string> names, IEnumerable<int> ages)
{
using (IEnumerator<int> ageIterator = ages.GetEnumerator())
{
foreach (string name in names)
{
if (!ageIterator.MoveNext())
{
throw new ArgumentException("Not enough ages");
}
Console.WriteLine("{0} is {1} years old", name, ageIterator.Current);
}
if (ageIterator.MoveNext())
{
throw new ArgumentException("Not enough names");
}
}
}
同樣也可以是,如果你想治療(說)不同的使用迭代器的第一個項目到受用:
public T Max<T>(IEnumerable<T> items)
{
Comparer<T> comparer = Comparer<T>.Default;
using (IEnumerator<T> iterator = items.GetEnumerator())
{
if (!iterator.MoveNext())
{
throw new InvalidOperationException("No elements");
}
T currentMax = iterator.Current;
// Now we've got an initial value, loop over the rest
while (iterator.MoveNext())
{
T candidate = iterator.Current;
if (comparer.Compare(candidate, currentMax) > 0)
{
currentMax = candidate;
}
}
return currentMax;
}
}
現在,如果你對IEnumerator<T>
和IEnumerable<T>
之間的區別感興趣,您可能想要用數據庫術語思考它:將IEnumerable<T>
作爲表,將IEnumerator<T>
作爲遊標。您可以請求一個表給您一個新的遊標,並且您可以同時在同一個表上有多個遊標。
可能需要一段時間才能真正理解這種差異,但只要記住一個列表(或數組,或其他)沒有任何「你在列表中的位置」的概念,而是在列表/ array/whatever does有那麼點的狀態是有幫助的。
8
喬恩說什麼。
IEnumerable
或IEnumerable<T>
:通過實施此對象指出,它可以給你,你可以用它來遍歷在序列/集合的迭代器/集IEnumerator
或IEnumerator<T>
:如果你調用定義GetEnumerator方法在前一個界面中,您將獲得一個迭代器對象作爲IEnumerator引用。這使您可以調用MoveNext()並獲取當前對象。foreach
:從某種意義上說,它是C#構造/外觀,因爲您不需要知道它如何在引擎蓋下工作。它在內部獲取迭代器併爲您調用正確的方法專注於您想要對每個項目執行的操作(foreach塊的內容)。大多數情況下,除非實現自己的類型或自定義迭代,否則只需要foreach,在這種情況下,您需要了解前2個接口。
6
記住,你不有來實現IEnumerator及其一些變體使用的foreach - IIRC,它需要一切是返回具有的MoveNext()方法返回一個對象的GetEnumerator()方法一個bool和一個Current屬性返回一個對象。您不需要使用IEnumerator和IEnumerable,但通常這是一個非常好的主意。有關更多信息,請參閱here。
相關問題
- 1. IEnumerable和IEnumerator的或foreach C#
- 2. IEnumerable&IEnumerator
- 3. foreach是否爲內置類型使用IEnumerator/IEnumerable?
- 4. IEnumerable&IEnumerator後綴
- 5. 是Yield Return == IEnumerable&IEnumerator?
- 6. C++/CLI IEnumerable和IEnumerator實現
- 7. 的IEnumerator IEnumerable的VB到C#
- 8. 什麼演員IEnumerable <T> IEnumerator <T>做
- 9. 什麼時候應該在IE中使用IEnumerator進行循環?
- 10. 當使用「yield」時,爲什麼編譯器生成的類型實現IEnumerable和IEnumerator
- 11. IEnumerator的目的是什麼
- 12. 尋找IEnumerable/IEnumerator更快的實現
- 13. 何時使用IEnumerable over IEnumerable <>
- 14. 爲什麼在IEnumerable上使用IList?
- 15. 爲什麼使用IQueryable代替IEnumerable與MEF目錄?
- 16. 什麼時候使用摺疊和何時在Scala中使用foreach
- 17. IEnumerable的<XElement>和foreach
- 18. foreach按字符串的IEnumerable引用
- 19. 如何在一個IEnumerable對象中執行foreach foreach
- 20. 的IEnumerable <T>和IEnumerator的 - 一些說明,請
- 21. 調用圖IEnumerator
- 22. 什麼時候使用StringBuilder.AppendLine/string.Format與StringBuilder.AppendFormat?
- 23. 什麼時候會使用ObjectInputStream.readUshared()與.readObject()?
- 24. Flex - Remoting與HTTPService - 什麼時候使用?
- 25. 什麼時候使用View()與RedirectToAction
- 26. 簡單IEnumerator使用(使用示例)
- 27. 返回IEnumerable <T>和IEnumerator <T>的迭代器方法有什麼區別嗎?
- 28. 當在IEnumerable上調用ToArray()時會發生什麼?
- 29. foreach與類的使用php
- 30. 使用forEach與Get-ChildItem -recurse
感謝喬恩爲你提供的所有幫助。我現在明白了,並且將會學習更多,以便說清楚。 另外我發現下面的鏈接非常有用: http://stackoverflow.com/questions/558304/can-anyone-explain-ienumerable-and-ienumerator-to-me – Wondering 2009-07-06 07:12:43
這是一個例子,你堅持使用IEnumerator只是保持高效。 http://stackoverflow.com/questions/1018407/what-is-the-most-elegant-way-to-get-a-set-of-items-by-index-from-a-collection/1025137#1025137 – 2009-07-06 11:59:04
@Jon Skeet我真的很喜歡你編碼方式Max的方法。我有一個問題。你使用IEnumberator構造。我知道使用處理它裏面的東西()。你爲什麼在IEnumberator上使用它? –
2012-05-29 05:47:38