使用 yield return 指令傳回匿名型別集合物件

  • 30424
  • 0
  • LINQ
  • 2013-08-14

在整個 LINQ 技術中, IEnumerable 這個介面可以說就是個主角。而當我們在方法中傳回實作 IEnumerable 介面的物件集合時, 我們可以使用 yield return 來取代原來的 return 指令...

 

在整個 LINQ 技術中, IEnumerable<T> 這個介面可以說就是個主角。而當我們在方法中傳回實作 IEnumerable 介面的物件集合時, 我們可以使用 yield return 來取代原來的 return 指令。

這個 yield return 指令在最早的 .NET 中是不存在的; 它在 2.0 版本中, 為因應通用型別集合物件的產生, 才開始存在。它的用法和 return 一樣, 只不過 return 指令會立即結束方法, 而 yield return 並不會立即結束方法, 而僅僅結束當下的迴圈, 並讓程序採用集合中的下一個參數。

我想, 上面那幾行拗口的描述可能會讓你愈看愈不懂; 我們不妨直接看個例子好了:

public string Test1(string str)
{
   return "Hello, " + str;
}

public IEnumerable<string> Test2(string col)
{
   string[] arr = col.Split(" ");
   foreach (string str in arr)
      yield return "Hello, " + str;
}

我想, 看了這個例子, 你應該就了解 yield return 和 return 有什麼不同了。如上例, 在 Test2 方法中, yield return 會配合 foreach 迴圈, 每次丟出一個字串, 直到 foreach 迴圈結束為止。而且它所丟出的字串, 會自動附加到將被回傳的 IEnumerable 集合物件裡面, 最後再一併回傳。

不過這裡還有一個問題。如果你想要對讀進來的每個參數進行檢查, 你可以中斷迴圈嗎? 當然可以, 你可以使用 yield break。範例如下:

public IEnumerable<string> Test3(string col)
{
   string[] arr = col.Split(" ");
   int num;
   foreach (string str in arr)
   {
      if (int.TryParse(str, out num))
         yield return str.ToString();
      else
         yield break;
   }
}

照這個做法, 當你執行到 yield break 指令時, 迴圈會被中斷, 而只有已經被加入集合者會被傳回, 當未被處理的則會被捨棄。在上例中, 假設你傳入的字串參數是 "1 2 3a 4 5", 那麼經處理後, 傳回的結果是 "1", "2"。


Dev 2Share @ 點部落