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使用的人則較難讀懂程式。

 

參考資料:

yield (C# 參考)

C# - yeild return 使用方法