如何在 C# 中使用 yield
yield關鍵詞是在 C# 2.0 中被引入的,我們都知道實現了 IEnumerable 接口的類都可以用于被 foreach 迭代,這是因為 IEnumerable 接口中提供了一個可迭代的 GetEnumerator() 方法,代碼定義如下:
public?interface?IEnumerable{IEnumerator?GetEnumerator();}現在你也可以使用 yield 關鍵詞來指定某些方法也是可以被迭代的,通常 C# 中有兩種 yield 的語法格式:yield return <expression> 和 yield break。
為什么要使用 yield 關鍵詞
yield關鍵詞可以實現一種 狀態迭代 而不需要提前創建好一個臨時集合,換句話說,當你在迭代器中使用 yield return 時,在數據返回之前你不需要創建一個臨時集合來存儲數據,你可以利用 yield return 一次性返回集合中的每項數據,同時你也可以在方法和get訪問器中使用帶有迭代的 yield return 語句,值得注意的是,當每次執行 yield return 語句后,控制權都會轉交給調用者。
說了這么多,如果有點懵的話,我們來看一個例子,下面的代碼展示了如何使用 yield 關鍵詞來返回 Fibonacci 數字,這個方法接收一個int類型的參數。
static?IEnumerable<int>?GenerateFibonacciNumbers(int?n){for?(int?i?=?0,?j?=?0,?k?=?1;?i?<?n;?i++){yield?return?j;int?temp?=?j?+?k;j?=?k;k?=?temp;}}上面的代碼中 yield return j 在不退出 for 循環的情況下逐個返回斐波那契數,換句話說,這個迭代狀態是被保留的,下面的代碼展示了如何調用 GenerateFibonacciNumbers()。
foreach?(int?x?in?GenerateFibonacciNumbers(10)){Console.WriteLine(x);}下面是僅供參考的完整代碼。
class?Program{static?void?Main(string[]?args){foreach?(int?x?in?GenerateFibonacciNumbers(10)){Console.WriteLine(x);}}static?IEnumerable<int>?GenerateFibonacciNumbers(int?n){for?(int?i?=?0,?j?=?0,?k?=?1;?i?<?n;?i++){yield?return?j;int?temp?=?j?+?k;j?=?k;k?=?temp;}}}也許你注意到了,上面的代碼并沒有創建一個 list 或者 array 去存放那些輸出到控制臺的斐波那契額數。
yield 關鍵詞的另一個優點在于可以按需創建和返回你需要的數,下面的代碼展示了 Get方法器 中僅返回 1-10 之間的偶數。
public?static?IEnumerable<int>?EvenNumbers{get{for?(int?i?=?1;?i?<=?10;?i++){if?((i?%?2)?==?0)yield?return?i;}}}你也可以使用 yield break 來提前中斷一個迭代鏈,如下代碼所示:
public?IEnumerable<T>?GetData<T>(IEnumerable<T>?items){if?(null?==?items)yield?break;foreach?(T?item?in?items)yield?return?item;}幾點原則
當你在用 yield 時,請記住如下幾點。
yield return 不能套在 try-catch 中,否則會報錯。
yield break 不能放在 finally 中。
yield 方法的返回類型只能是 IEnumerable, IEnumerable<T>, IEnumerator,IEnumerator<T>。
在 yiled 的方法參數中不能使用 ref,out 標記。
不能將 yield return 和 yield break 放在匿名方法中。
不能將 yield return 和 yield break 放在 unsafe 方法中。
譯文鏈接:https://www.infoworld.com/article/3122592/my-two-cents-on-the-yield-keyword-in-c.html
總結
以上是生活随笔為你收集整理的如何在 C# 中使用 yield的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ASP.NET Core 基于角色的 J
- 下一篇: 如何在 C#9 中使用顶级程序 (top