yield
例如一個方法處理輸入一集合,將該集合經過篩選,
只會挑出帶有「Math」字串並回傳。而我很直覺的做法是
在方法內先宣告一個空集合,然後再把符合條件的字串全都放在集合裡並回傳。
using System;
using System.Collections.Generic;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
List<string> inputs = new List<string>() { "Math.abs", "Math.acos", "DateTime.Now", "DateTime.Today" };
IEnumerable<string> results;
results = TestYield(inputs);
Console.WriteLine(@"list to included string ""Math""");
foreach (var item in results)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
static List<string> TestYield(List<string> results)
{
List<string> temps = new List<string>();
foreach (var item in results)
{
if (item.Contains("Math"))
{
temps.Add(item);
}
}
return temps;
}
}
}
但是使用「yield」關鍵字並與「return」搭配,
而且還會跟Iterator(迭代器)配合例如「foreach」,
則意思是每次iterate(遍歷)後,會先保留該元素的位置,
等到Iterator(迭代器)裡的元素都跑完一輪後,再一次回傳所有位置而成為集合。
如下「foreach」中再加上判斷式,則表示成回傳符合條件的集合。
using System;
using System.Collections.Generic;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
List<string> inputs = new List<string>() { "Math.abs", "Math.acos", "DateTime.Now", "DateTime.Today" };
IEnumerable<string> results;
results = TestYield(inputs);
Console.WriteLine(@"list to included string ""Math""");
foreach (var item in results)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
static IEnumerable<string> TestYield(List<string> results)
{
foreach (var item in results)
{
if (item.Contains("Math"))
{
yield return item;
}
}
}
}
}
注意yield使用上有一些限制
1、回傳類型必須為IEnumerable, IEnumerable<T>, IEnumerator, IEnumerator<T>
2、不可包含任何 ref 與 out 參數
心得:使用yield後讓程式碼更簡潔了,但對不熟yield使用的人則較難讀懂程式。
參考資料: