標籤:
yield(C# 參考)在語句中使用 yield 關鍵字,表示在該關鍵字所在的方法、運算子或 get 訪問器是迭代器。 通過使用 yield 定義迭代器,可在實現自訂集合類型的 IEnumerable 和 IEnumerator 模式時無需其他顯式類(保留枚舉狀態的類,有關樣本,請參閱 IEnumerator<T>)。
下面的樣本示範了 yield 語句的兩種形式。
複製
yield return <expression>;yield break;
備忘
使用 yield return 語句可一次返回一個元素。
通過 foreach 語句或 LINQ 查詢來使用迭代器方法。 foreach 迴圈的每次迭代都會調用迭代器方法。 迭代器方法運行到 yield return 語句時,會返回一個 expression,並保留當前在代碼中的位置。 當下次調用迭代器函數時執行從該位置重新啟動。
可以使用 yield break 語句來終止迭代。
有關迭代器的詳細資料,請參閱迭代器(C# 和 Visual Basic)。
迭代器方法和 get 訪問器
迭代器的聲明必須滿足以下要求:
返回 IEnumerable 或 IEnumerator 的迭代器的 yield 類型為 object。如果迭代器返回 IEnumerable<T> 或 IEnumerator<T>,則必須將 yield return 語句中的運算式類型隱式轉換為泛型型別參數。
你不能在具有以下特點的方法中包含 yield return 或 yield break 語句:
異常處理
不能將 yield return 語句置於 try-catch 塊中。 可將 yield return 語句置於 try-finally 語句的 try 塊中。
yield break 語句可以位於 try 塊或 catch 塊,但不能位於 finally 塊。
如果 foreach 主體(在迭代器方法之外)引發異常,則將執行迭代器方法中的 finally 塊。
技術實現
以下代碼從迭代器方法返回 IEnumerable<string>,然後遍曆其元素。
C#複製
IEnumerable<string> elements = MyIteratorMethod();foreach (string element in elements){ …}
調用 MyIteratorMethod 並不執行該方法的主體。 相反,該調用會將 IEnumerable<string> 返回到 elements 變數中。
在 foreach 迴圈迭代時,將為 elements 調用 MoveNext 方法。 此調用將執行 MyIteratorMethod 的主體,直至到達下一個 yield return 語句。 yield return 語句返回的運算式不僅決定了迴圈體使用的 element 變數值,還決定了元素的 Current 屬性(它是 IEnumerable<string>)。
在 foreach 迴圈的每個後續迭代中,迭代器主體的執行將從它暫停位置繼續,直至到達 yield return 語句後才會停止。 在到達迭代器方法的結尾或 yield break 語句時,foreach 迴圈便已完成。
樣本
下面的樣本包含一個位於 for 迴圈內的 yield return 語句。 Process 中的 foreach 語句體的每次迭代都會建立對 Power 迭代器函數的調用。 對迭代器函數的每個調用將繼續到 yield return 語句的下一次執行(在 for 迴圈的下一次迭代期間發生)。
迭代器方法的傳回型別是 IEnumerable(一種迭代器介面類型)。 當調用迭代器方法時,它將返回一個包含數字冪的可枚舉對象。
C#複製
public class PowersOf2{ static void Main() { // Display powers of 2 up to the exponent of 8: foreach (int i in Power(2, 8)) { Console.Write("{0} ", i); } } public static System.Collections.Generic.IEnumerable<int> Power(int number, int exponent) { int result = 1; for (int i = 0; i < exponent; i++) { result = result * number; yield return result; } } // Output: 2 4 8 16 32 64 128 256}樣本
下面的樣本示範一個作為迭代器的 get 訪問器。 在該樣本中,每個 yield return 語句返回一個使用者定義的類的執行個體。
C#複製
public static class GalaxyClass{ public static void ShowGalaxies() { var theGalaxies = new Galaxies(); foreach (Galaxy theGalaxy in theGalaxies.NextGalaxy) { Debug.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears.ToString()); } } public class Galaxies { public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy { get { yield return new Galaxy { Name = "Tadpole", MegaLightYears = 400 }; yield return new Galaxy { Name = "Pinwheel", MegaLightYears = 25 }; yield return new Galaxy { Name = "Milky Way", MegaLightYears = 0 }; yield return new Galaxy { Name = "Andromeda", MegaLightYears = 3 }; } } } public class Galaxy { public String Name { get; set; } public int MegaLightYears { get; set; } }}
有關更多資訊,請參見C# 語言規範。 該語言規範是 C# 文法和用法的權威資料。
yield(C# 參考)