日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

迭代器和yield

發布時間:2023/12/13 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 迭代器和yield 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  2012-08-05?tc莊稼漢

  迭代器是一種方法、get 訪問器或運算符,它通過使用 yield 關鍵字對數組或集合類執行自定義迭代。 yield 返回語句會導致源序列中的元素在訪問源序列中的下一個元素之前立即返回給調用方。 盡管您以方法的形式編寫迭代器,但編譯器會將其轉換為一個實際上是狀態機的嵌套類。 只要客戶端代碼中的 foreach 循環繼續進行,此類就會跟蹤迭代器的位置。

  將使用 foreach 語句從客戶端代碼中調用迭代器。 例如,您可以為類創建一個迭代器,該迭代器將按相反順序返回元素,或在迭代器返回元素之前對每個元素執行操作。 在為類或結構創建迭代器時,您不必實現整個 IEnumerator 接口。 當編譯器檢測到迭代器時,它將自動生成 IEnumerator 或 IEnumerator<T> 接口的 Current、MoveNextDispose 方法。
一、迭代器概述

  • 迭代器是可以返回相同類型的值的有序序列的一段代碼。

  • 迭代器可用作方法、運算符或 get 訪問器的代碼體。

  • 迭代器代碼使用 yield return 語句依次返回每個元素。 yield break 將終止迭代。

  • 可以在類中實現多個迭代器。 每個迭代器都必須像任何類成員一樣有唯一的名稱,并且可以在 foreach 語句中被客戶端代碼調用,如下所示:foreach(int x in SampleClass.Iterator2){}

  • 迭代器的返回類型必須為 IEnumerable、IEnumerator、IEnumerable<T> 或 IEnumerator<T>。

  • 迭代器是 LINQ 查詢中延遲執行行為的基礎。

  yield 關鍵字用于指定返回的一個或多個值。 到達 yield return 語句時,會保存當前位置。 下次調用迭代器時將從此位置重新開始執行。

  迭代器對集合類特別有用,它提供一種簡單的方法來迭代復雜的數據結構(如二進制樹)。
二、yield關鍵字
  

  yield 關鍵字向編譯器指示它所在的方法是迭代器塊。 編譯器生成一個類來實現迭代器塊中表示的行為。 在迭代器塊中,yield 關鍵字與 return 關鍵字結合使用,向枚舉器對象提供值。 這是一個返回值,例如,在 foreach 語句的每一次循環中返回的值。 yield 關鍵字也可與 break 結合使用,表示迭代結束。 有關迭代器的更多信息,請參見迭代器(C# 編程指南)。

  使用迭代塊,編譯器會生成一個yield類型,其中包含一個狀態機,yield類型執行IEnumerator和IDisposable接口的屬性和方法.GetEnumerator()方法實例化并返回一個新的yield類型.在yield類型中,變量state定義了迭代的當前位置,每次調用MoveNext()時,當前位置都會改變.MoveNext()封裝了迭代塊的代碼,設置了current變量的值,使Current屬性根據位置返回一個對象。

下面的示例演示兩種形式的 yield 語句。
  

yield return <expression>; yield break;

?

  yield注意事項:  

  在 yield return 語句中,將計算 expression 并將結果以值的形式返回給枚舉器對象;expression 必須可以隱式轉換為 yield 類型的迭代器。

  在 yield break 語句中,控制權將無條件地返回給迭代器的調用方,該調用方為枚舉器對象的 IEnumerator.MoveNext 方法(或其對應的泛型 System.Collections.Generic.IEnumerable<T>)或 Dispose 方法。

  yield 語句只能出現在 iterator 塊中,這種塊可作為方法、運算符或訪問器的主體實現。 這類方法、運算符或訪問器的體受以下約束的控制:

  • 不允許不安全塊。

  • 方法、運算符或訪問器的參數不能是 ref 或 out。

  • yield return 語句不能放在 try-catch 塊中的任何位置。 該語句可放在后跟 finally 塊的 try 塊中。

  • yield break 語句可放在 try 塊或 catch 塊中,但不能放在 finally 塊中。

  yield 語句不能出現在匿名方法中。 有關更多信息,請參見 匿名方法(C# 編程指南)。

  當和 expression 一起使用時,yield return 語句不能出現在 catch 塊中或含有一個或多個 catch 子句的 try 塊中。 有關更多信息,請參見 異常處理語句(C# 參考)。

三、使用迭代器
  
1.創建迭代器最常用的方法是對 IEnumerable 接口實現 GetEnumerator 方法,例如:

public System.Collections.IEnumerator GetEnumerator() {for (int i = 0; i < 10; i++){yield return i;} }

?

  GetEnumerator 方法的存在使得類型成為可枚舉的類型,并允許使用 foreach 語句。 如果上面的方法是 ListClass 的類定義的一部分,則可以對該類使用 foreach,如下所示:
  

static void Main() {ListClass listClass1 = new ListClass();foreach (int i in listClass1){System.Console.Write(i + " ");}// Output: 0 1 2 3 4 5 6 7 8 9 }

?

  foreach 語句調用 ListClass.GetEnumerator() 并使用返回的枚舉數來循環訪問值。

  2.還可以使用命名的迭代器以支持通過不同的方式循環訪問同一數據集合。 例如,您可以提供一個按升序返回元素的迭代器,而提供按降序返回元素的另一個迭代器。 迭代器還可以帶有參數,以便允許客戶端控制全部或部分迭代行為。 下面的迭代器使用命名的迭代器 SampleIterator 實現 IEnumerable 接口:
  

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

?

  命名的迭代器的調用方法如下(ps:第一種實現GetEnumerator方法,實際上就是定義一個支持IEnumerable或者IEnumrator的可枚舉類型,所以foreach (int i in listClass1),這里的listClass1是listClass類型的實例對象,而下面這個foreach (int n in test.SampleIterator(1, 10))就是使用的迭代器的名稱。):
  

ListClass test = new ListClass();foreach (int n in test.SampleIterator(1, 10)) {System.Console.Write(n + " "); } // Output: 1 2 3 4 5 6 7 8 9 10

?

  可以在同一個迭代器中使用多個 yield 語句,如下面的示例所示:
  

public System.Collections.IEnumerator GetEnumerator() {yield return "With an iterator, ";yield return "more than one ";yield return "value can be returned";yield return "."; }

?

  然后可以使用下面的 foreach 語句輸出結果:
  

foreach (string element in new TestClass()) {System.Console.Write(element); } // Output: With an iterator, more than one value can be returned.

?

  此示例顯示以下文本:

  With an iterator, more than one value can be returned.

  在 foreach 循環的每次后續迭代(或對 IEnumerator.MoveNext 的直接調用)中,下一個迭代器代碼體將從前一個 yield 語句之后開始,并繼續下一個語句直至到達迭代器體的結尾或遇到 yield?break 語句。

  迭代器不支持 IEnumerator.Reset 方法。 若要從頭開始重新循環訪問,必須獲取新迭代器。

轉載于:https://www.cnblogs.com/shandong/archive/2012/08/05/2623989.html

總結

以上是生活随笔為你收集整理的迭代器和yield的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。