1. 程式人生 > WINDOWS開發 >[c#] 理解與使用 yield

[c#] 理解與使用 yield

理解 yield 原始碼

比如我們有一段 code 如下所示:

public class Yield : IDemoBase
{
    public static IEnumerable<int> GetList(int[] nums)
    {
        foreach (var num in nums)
        {
            yield return num;
        }
    }

    public void Run()
    {
        var list = GetList(new int[] { 1,2,3,4,5 });
    }
}

反編譯一下看看原始碼:

技術分享圖片

可以理解為帶有 yield 語法糖的方法,getList() 在編譯後,底層實際上多了一個方法叫做: <getList>d_x

技術分享圖片

實際上底層實現了一個迭代器,這個實現其實和設計模式中迭代模式很相似. 反過來推,當我們不使用 yield 時,自己手寫需要寫這麼多程式碼.

使用 yield

仔細品下面兩段程式碼的區別?

public void Run()
{
    IEnumerable<int> items = GetList_v2(new int[] { 1,5 });
    Console.WriteLine("Begin to iterate the items from GetList_v2.");
    foreach (var item in items)
    {
        Console.WriteLine(item);
    }

    items = GetList_v3(new int[] { 6,7,8,9,10 });
    Console.WriteLine("Begin to iterate the items from GetList_v3.");
    foreach (var item in items)
    {
        Console.WriteLine(item);
    }
}

public IEnumerable<int> GetList_v2(int[] nums)
{
    Console.WriteLine("Begin to invoke GetList_v2() method");
    return nums.Where(num => num % 2 == 0);
}

public IEnumerable<int> GetList_v3(int[] nums)
{
    Console.WriteLine("Begin to invoke GetList_v3() method");
    foreach (var num in nums)
    {
        if (num % 2 == 0) yield return num;
    }
}

GetList_v2 和 GetList_v3 都是具備一定業務邏輯處理能力的方法,並返回處理後的資料集合.

區別只是是否使用了 yield 關鍵字. 執行下看看:

技術分享圖片

可能已經看出來區別了就是 GetList_v3 與 GetList_v2 程式碼實際執行的實際不一樣. GetList_v3 我們可以理解為當有真正的資源消費方時才真正執行.

reference

感謝:

c# yield關鍵字的用法