Lambda表達式

来源:https://www.cnblogs.com/taotaozhuanyong/archive/2019/09/18/11541539.html
-Advertisement-
Play Games

lambda演變歷史 .NetFramework1.0 1.1下,lambda表達式是這樣去寫的,首先聲明一個無參無返回值delegate委托,再聲明一個無參無返回值的方法,把這個方法當做參數一樣傳遞給委托 你也可以聲明一個有參數和有返回值的委托,就像聲明方法一樣: .NetFramework2.0 ...


lambda演變歷史

  .NetFramework1.0  1.1下,lambda表達式是這樣去寫的,首先聲明一個無參無返回值delegate委托,再聲明一個無參無返回值的方法,把這個方法當做參數一樣傳遞給委托

        public delegate void NoReturnNoPara();
        NoReturnNoPara method = new NoReturnNoPara(this.DoNothing);
        private void DoNothing()
        {
            Console.WriteLine("This is DoNothing");
        }

  你也可以聲明一個有參數和有返回值的委托,就像聲明方法一樣:

public delegate void NoReturnWithPara(int x, string y);//1 聲明委托
NoReturnWithPara method = new NoReturnWithPara(this.Study);
        private void Study(int id, string name)
        {
            Console.WriteLine($"{id} {name} 學習.Net高級班");
        }
//method.Invoke(123, "strPram");
method(123,"strParm");//這兩種調用方式是等效的

  .NetFramework2.0  匿名方法,delegate關鍵字,可以訪問局部變數

                NoReturnWithPara method = new NoReturnWithPara(delegate (int id, string name)
                {
                    Console.WriteLine(i);
                });
                method.Invoke(234, "bingle");

  .NetFramework3.0   把delegate關鍵字去掉,增加了一個箭頭goes to,lambda表達式  參數列表=>方法體

 NoReturnWithPara method = new NoReturnWithPara(
     (int id, string name) =>
 {
     Console.WriteLine($"id:{id},name: {name}");
 });
 method.Invoke(123, "bingle");

  省略參數類型,編譯器的語法糖,雖然沒寫,編譯時還是有的,根據委托推算

 NoReturnWithPara method = new NoReturnWithPara(
     (id, name) =>
     {
         Console.WriteLine($"id:{id}name: {name}");
     });
 method.Invoke(123, "bingle");

如果方法體只有一行,可以去掉大括弧和分號

NoReturnWithPara method = new NoReturnWithPara(
    (id, name) => Console.WriteLine($"id:{id},name: {name} "));
method.Invoke(123, "bingle");

new NoReturnWithPara可以省掉,也是語法糖,編譯器自動加上

 NoReturnWithPara method = (id, name) => Console.WriteLine($"id:{id} ,name:{name}");
 method.Invoke(123, "bingle"); 

lambda是什麼?

  lambda只是實例化委托,是匿名方法,但是在編譯的時候會分配一個名字,還會產生一個私有sealed類,這裡增加一個剛發

lambda在多播委托

 NoReturnWithPara method = new NoReturnWithPara(this.Study);
 method += this.Study;
 method += (id, name) => Console.WriteLine($"{id} {name}");

 method -= this.Study;
 method -= (id, name) => Console.WriteLine($"{id} {name} ");
 //多播委托裡面的lambda無法移除, 不是2個實例,其實是2個不同的方法
 method.Invoke(345, "bingle");

匿名方法或者lamdba表達式是不是只能是無返回值的?不是的,可以有返回值的。這裡面的Action和Func是內置的委托

Action action0 = () => { };
Action<string> action1 = s => Console.WriteLine(s); //參數只有一個  可以省略小括弧
Func<int> func0 = () => DateTime.Now.Month;//如果方法體只有一行,去掉大括弧分號return
int iResult = func0.Invoke();

yield關鍵字:

  含有yield的函數說明它是一個生成器,而不是普通的函數。當程式運行到yield這一行時,該函數會返回值,並保存當前域的所有變數狀態。

  等到該函數下一次被調用時,會從上一次中斷的地方開始執行,一直遇到下一個yield,程式返回值,併在此保存當前狀態;如此反覆,知道函數正常執行完成。

  迭代器模式是設計模式中行為模式的一個例子,他是一種簡化對象間通訊的模式,也是一種非常容易理解和使用的模式。

  簡單來說,迭代器模式使得你能夠獲取到序列中的所有元素,而不用關心器類型是array,list,linked或者其他的什麼序列結構。

  這一點使得能夠非常搞笑的構建數據處理通道(data  pipeline),即數據能夠進入處理通道,進行一系列的變換,活著過濾,然後得到結果。事實上,這正是Linq的核心模式。

  在.NET中,迭代器模式被IEnumerator和IEnumerable及其對應的泛型介面所封裝。如果一個類實現了IEnumerable介面,那麼就能夠被迭代。

  調用GetEnumerator方法將返回IEnumerator介面的實現,它就是迭代器本身。迭代器類似資料庫中的游標,它是數據序列中的一個位置記錄。

  迭代器只能向前移動,同一個數據序列中跨域有多個迭代器同時對數據進行操作。

 

一個普通的獲取數據的方法:

 public IEnumerable<int> CommonMethod()
 {
     List<int> results = new List<int>();
     int counter = 0;
     int result = 1;

     while (counter++ < 10)
     {
         Thread.Sleep(1000);
         Console.WriteLine($"獲取{counter}次數據");
         result = result * 2;
         results.Add(result);
     }
     return results;
 }

yield獲取數據:

 public IEnumerable<int> YieldMethod()
 {
     int counter = 0;
     int result = 1;
     while (counter++ < 10)
     {
         Thread.Sleep(1000);
         Console.WriteLine($"獲取{counter}次數據");
         result = result * 2;
         yield return result;
     }
 }

這兩個方法,可以通過調試看到他們之間的區別

這是普通方法獲取數據的調試結果:

 

 這是yield方法調試獲得的結果:

 

 

public IEnumerable<int> CreateEnumerable()
{
    try
    {
        Console.WriteLine("{0} CreateEnumerable()方法開始", DateTime.Now);
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine("{0}開始 yield {1}", DateTime.Now, i);
            yield return i;
            Console.WriteLine("{0}yield 結束", DateTime.Now);
            if (i == 4)
            {
                yield break;//直接終結迭代  4會出現的,,
            }
        }
        Console.WriteLine("{0} Yielding最後一個值", DateTime.Now);
        yield return -1;
        Console.WriteLine("{0} CreateEnumerable()方法結束", DateTime.Now);
    }
    finally
    {
        Console.WriteLine("停止迭代!");
    }
}




IEnumerable<int> iterable = new Test().CreateEnumerable();//1 不會直接執行
IEnumerator<int> iterator = iterable.GetEnumerator();
Console.WriteLine("開始迭代");
while (true)
{
    Console.WriteLine("調用MoveNext方法……");
    Boolean result = iterator.MoveNext();//2 正式開啟CreateEnumerable
    Console.WriteLine("MoveNext方法返回的{0}", result);
    if (!result)
    {
        break;
    }
    Console.WriteLine("獲取當前值……");
    Console.WriteLine("獲取到的當前值為{0}", iterator.Current);
}

 

這是調試獲得的結果:

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 代碼地址: "DotNetCore_Practice/JavaToC /DigestUtils at master · PuzzledAlien/DotNetCore_Practice" ...
  • 一個簡單的批量二維碼生成器 最近需要將大量的字元串生成二維碼, 網上找了很多網站和應用都不是很理想,乾脆自己做了吧! github 上找了下找到QrCode 開源項目 QrCode 開源類庫 安裝qrcode非常簡單, "參考這裡" 引用 dll 核心邏輯 加個界面 功能完成了,如果要給其他人用還需 ...
  • 前言 面試以及考試過程中必會出現一道排序演算法面試題,為了加深對排序演算法的理解,在此我對各種排序演算法做個總結歸納。 1、冒泡排序演算法(BubbleSort) 1.1 演算法描述 (1)比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。 (2)對每一對相鄰元素做同樣的工作,從開始第一對到結尾的最後一對 ...
  • 前提 入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 碼雲:https://gitee.com/kwwwvagaa/net_winform_custom_contr ...
  • <Style x:Key="workButtonStyle" TargetType="{x:Type Button}"> <Style.Triggers> <Trigger Property="IsMouseOver" Value="False"> <Setter Property="FontSiz... ...
  • C#上手練習2(FOR語句) ...
  • 1.索引器的索引值類型不限定為整數 2.索引器允許重載 3.索引器不是一個變數 4.索引器以函數簽名方式this標識,而屬性採用名稱來標識,名稱可以任意 5.索引器不能使用static來進行聲明,屬性可以。索引器永遠屬於實例成員,因此不能聲明為static。 ...
  • 1、列印字元串。 2、調用簡單方法,方法里有if語句、Swich語句。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...