2014-02-13 102 views
2

(新的C#) 有人能解釋一下,爲什麼叫迭代器(學期我MS C#編程手冊中找到)應返回IEnumerable爲什麼要爲指定的迭代器返回IEnumerable?

// Implementing the enumerable pattern 
public System.Collections.IEnumerable SampleIterator(int start, int end) 
{ 
    for (int i = start; i <= end; i++) 
    { 
     yield return i; 
    } 
} 

這是有道理的,當類實現IEnumerableIEnumerable<T>接口GetEnumerator(),但我不知道爲什麼以及它如何工作的方法和屬性。

編輯:有人指出我的問題沒有得到很好的構成(或許,我還是用C來思考++) 澄清:爲了使用foreach環路上的一些類的對象,類需要實現IEnumerableIEnumerator接口或yield return(即編譯器負責處理所有內容)。 例子:

class ListClass : System.Collections.IEnumerable 
{ 
    public System.Collections.IEnumerator GetEnumerator() {...//uses yield return } 
    .... 
} 
    .... 
    ListClass listClass1 = new ListClass(); // class implements IEnumerable interface method 
    foreach (int i in listClass1) {...} 

在上面的例子中,GetEnumerator()開始實施,其中,據我的理解,必須執行,如果你想你的對象在foreach循環運行。 但是,當實現指定的迭代器時(上面的代碼),GetEnumerator()不是必需的,只有IEnumberable<T>(或非泛型)必須由方法/屬性返回。
希望這可以澄清我的問題。

+4

這真不明白你的意思。該方法正在返回一個可迭代/可枚舉對象的引用......你能更清楚地解釋你的困惑嗎? (我意識到這可能很難。) –

+0

你有什麼選擇? –

回答

4

其實,我想說它應該返回IEnumerable<T> - 或IEnumerable<int>在這種情況下。但原因是,因爲它的工作原理是,並且因爲迭代器塊(使用yield語法的方法)可以爲您實現該模式。如果你想做一些別的foreach工作,你會寫自己的CustomEnumerable/CustomIterator,並手動實現狀態機的迭代器,使用MoveNext()/Current模式,記住把任何finally等在Dispose()。很多工作;收益不大。


編輯:這是一個寫得很差的,可能是錯誤的執行方式,即手動返回自定義迭代器。需要注意的是返回一個int[]List<int>將是很簡單的,但顯著改變語義:它不再是一個假脫機迭代器,這是yield創建:

static CustomEnumerable SampleIteratorHard(int start, int end) 
{ 
    return new CustomEnumerable(start, end); 
} 
class CustomEnumerable 
{ 
    private readonly int start, end; 
    public CustomEnumerable(int start, int end) 
    { 
     this.start = start; 
     this.end = end; 
    } 
    public CustomIterator GetEnumerator() 
    { 
     return new CustomIterator(start, end); 
    } 
} 
class CustomIterator 
{ 
    private readonly int start, end; 
    int i, state, value; 
    public CustomIterator(int start, int end) 
    { 
     this.start = start; 
     this.end = end; 
     start = 0; 
    } 
    public bool MoveNext() 
    { 
     if (state == 2) return false; 
     if (state == 0) 
     { 
      i = start - 1; // to leave space for the ++ 
      state = 1; 
     } 
     if (state == 1) 
     { 
      i++; 
      if (i <= end) 
      { 
       value = i; 
       return true; 
      } 
     } 
     state = 2; 
     return false; 
    } 
    public int Current { get { return value; } } 
} 
相關問題