C#.Net工作筆記009---c#中Yield Return語法的作用和好處

技術交流QQ羣【JAVA,C++,Python,.NET,BigData,AI】:170933152  

看到項目裏用到了,查了一下,這個的作用是:

yield return會對當前執行的 保存,阻塞當前函數進程,然後回到當前執行的地方,這樣有個好處,如果處理大量數據的話,

會處理一條,便顯示一條,這樣的話,不必要讓用戶等太久才能看到結果.

 

還是數據和以前一樣,我先上代碼,請大家先拿到我的代碼或者你跟着敲,運行看效果,以及理解每行帶代碼的作用。 
我們要帶着爲什麼要用Yield這個關鍵字,不用可以嗎這個目的去學知識,我相信會更加的有意思。

首先我貼出平時正常輸出偶數集合的辦法

/*
 *
 *  學習Yield Return 語法
 *  使用兩個方法,顯示1 - 100之間的全部偶數
 * 
 * 
 */

using System;
using System.Collections.Generic;


namespace YieldReturn語法解析
{
    class Program
    {
       static  private List<int> _numArray; //用來保存1-100 這100個整數

        Program() //構造函數。我們可以通過這個構造函數往待測試集合中存入1-100這100個測試數據
        {
            _numArray = new List<int>(); //給集合變量開始在堆內存上開內存,並且把內存首地址交給這個_numArray變量

            for (int i = 1; i <= 100; i++) 
            {
                _numArray.Add(i);  //把1到100保存在集合當中方便操作
            }
        }

        static void Main(string[] args)
        {
            new Program();

            TestMethod();


        }

        //測試求1到100之間的全部偶數
        static  public void TestMethod()
        {
            foreach (var item in GetAllEvenNumber()) 
            {
                Console.WriteLine(item); //輸出偶數測試
            }
        }

        //測試我們正常情況下拿到全部偶數的方法
       static  IEnumerable<int> GetAllEvenNumber()
        {
            List<int> result = new List<int>(); //開集合內存存偶數用

            foreach (int num in _numArray) 
            {
                if(num % 2 == 0) //判斷是不是偶數
                {
                    //yield return num;
                    result.Add(num); //存入集合
                }
            }

            //返回偶數集合變量   可能有人會覺得奇怪返回類型不是List<int>這樣可以嗎
            //這個就要回到我們的里氏替換原則了,子類是可以替換父類的,也就是當父類用
            //比如我這個方法是想得到IEnumerable<int> 類型變量,但是我給了List<int>類型變量
            //注意List<int> 是繼承 IEnumerable<int> 的,什麼意思當我們把子類當父類使用,
            //那麼大才小用,因爲子類很多都是繼承父親,你自身增加很多字段或者方法,這樣就不能用了。
            return result;  
            //yield break;
        }


    }
}

貼出使用Yiele Return辦法輸出耦合集合

/*
 *
 *  學習Yield Return 語法
 *  使用兩個方法,顯示1 - 100之間的全部偶數
 * 
 * 
 */

using System;
using System.Collections.Generic;


namespace YieldReturn語法解析
{
    class Program
    {
       static  private List<int> _numArray; //用來保存1-100 這100個整數

        Program() //構造函數。我們可以通過這個構造函數往待測試集合中存入1-100這100個測試數據
        {
            _numArray = new List<int>(); //給集合變量開始在堆內存上開內存,並且把內存首地址交給這個_numArray變量

            for (int i = 1; i <= 100; i++) 
            {
                _numArray.Add(i);  //把1到100保存在集合當中方便操作
            }
        }

        static void Main(string[] args)
        {
            new Program();

            TestMethod();


        }

        //測試求1到100之間的全部偶數
        static  public void TestMethod()
        {
            foreach (var item in GetAllEvenNumber()) 
            {
                Console.WriteLine(item); //輸出偶數測試
            }
        }

        //測試我們使用Yield Return情況下拿到全部偶數的方法
       static  IEnumerable<int> GetAllEvenNumber()
        {

            foreach (int num in _numArray) 
            {
                if(num % 2 == 0) //判斷是不是偶數
                {
                    yield return num; //返回當前偶數

                }
            }        
            yield break;  //當前集合已經遍歷完畢,我們就跳出當前函數,其實你不加也可以
            //這個作用就是提前結束當前函數,就是說這個函數運行完畢了。
        }


    }
}

大家測試了2個代碼結果沒,是不是都可以正確拿到全部偶數集合,具體我需要你們測,這樣進步快,纔會真是學會。只看不練假把戲。

現在我們說他們的區別: 
這個纔是真正要學的地方 
我們需要下斷點

我希望你是在斷點調試,具體就貼太多,你會發現代碼跑到Yield return num的時候,當前函數就會結束,並把這個num交給這裏,我先上圖

最終會給item變量。 
然後輸出,然後在執行 GetAllEvenNumber()方法,和上次得到偶數是一樣。 
我們發現這個Yield Return是可以讓當前函數的進程狀態切換到阻塞狀態,然後去選擇了把cpu交給當前的出進程,這樣就轉而執行調用方函數。 (補充個小知識點其實我們寫的程序加入到內存中,並不定就是一個進程,我們會根據情況分成幾個子進程去幹活,方便操作系統去管理以及多道程序運行在內存,提高計算機資源的利用率) 
這樣有個好處,我們假如有1000000個數據,我們需要得到裏面的耦合,當我們通過這個方法得到一個耦合會立馬顯示在控制檯上。而不是等很久也就把全部偶數都查找到存入集合當中,然後在一一遍歷輸出。 
這個好處是很大的。比如我們用戶可能就看數據開始肯定不是全部值需要部分就可以,看完這些在看後面的,這樣數據會讓覺得顯示沒有延遲。

下面我們來斷點調一般的查找偶數的函數

我們發現這個循環沒有跑完是不會退出當前函數的,也就是必須要查找全部的偶數纔可以。這樣假如我們很多數據。就會一直等這個數據纔可以拿到這個數據去顯示給用戶看。 
這樣就麻煩了。

因此我們下個結論:Yield Return關鍵字的作用就是退出當前函數,並且會保存當前函數執行到什麼地方,也就上下文。你發現沒下次執行這個函數上次跑來的代碼是不會重複執行的,

但是你一般的return result 假如你在循環體提前return ,下面調這個函數是會從第一步開始重新執行的。不會記錄上次執行的地方
--------------------- 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章