CSharp的lambda表達式匿名類擴展方法

来源:https://www.cnblogs.com/wenlong-4613615/p/18071142
-Advertisement-
Play Games

c#的lamba表達式 之前已經寫過一些關於委托還有事件的文章,今天就來介紹一下lambda表達式。 首先定義需要的函數以及委托 { public delegate void DoNothingDelegate(); public delegate void StudyDelegate(int id ...


c#的lamba表達式

之前已經寫過一些關於委托還有事件的文章,今天就來介紹一下lambda表達式。
首先定義需要的函數以及委托

{
public delegate void DoNothingDelegate();
public delegate void StudyDelegate(int id, string name);

private void DoNothing()
{
    Console.WriteLine("DoNothing");
}

private void Study(int id , string name)
{
    Console.WriteLine($"{id} {name} 學習 .Net高級班 " );
}
}

在.net farmwork 1.0,會這樣寫我們的匿名函數


   public void Show()
   {
       {
           //.netframework 1.0的寫法
           DoNothingDelegate doNothing = new DoNothingDelegate(DoNothing);
           StudyDelegate study = new StudyDelegate(Study);
       }
   }

在.netframework 2.0,會這樣寫匿名函數, 增加了一個delegate關鍵字

 {
     DoNothingDelegate doNothing = new DoNothingDelegate (delegate ()
     {
         Console.WriteLine("DoNothing");
     });
     StudyDelegate study = new StudyDelegate( delegate (int id, string name)
     {
         Console.WriteLine($"{id} {name} 學習 .Net高級班 ");
     });
 }

在.netframework3.0,去掉了delegate關鍵字了,在參數後增加了一個=> goes to

{
    DoNothingDelegate doNothing = new DoNothingDelegate(() =>
    {
        Console.WriteLine("DoNothing");
    });
    StudyDelegate study = new StudyDelegate((int id, string name) =>
    {
        Console.WriteLine($"{id} {name} 學習 .Net高級班 ");
    });
}

在.netframework3.0後期,我們可以省略參數的信息

 StudyDelegate study = new StudyDelegate((id, name) =>
 {
     Console.WriteLine($"{id} {name} 學習 .Net高級班 ");
 });

如果匿名方法體中只有一行代碼,可以省略方法題的大括弧

StudyDelegate study = new StudyDelegate((id, name) =>Console.WriteLine($"{id} {name} 學習 .Net高級班 "));

只有一個參數的時候,參數的小括弧也可以省略掉。

public delegate void StudyNew(int id);
StudyNew study = id => Console.WriteLine($"{id} 學習 .Net高級班 ");

如果方法返回值?
如果lambda表達式中只有一行代碼,且有返回值,可以省略return,

Func<int> retNum= () => 1;

lamba函數的本質是什麼?

這裡使用ilspy進行反編譯來看一下匿名方法的實現是怎麼樣的

img

本質上來說,其實就是一個方法--匿名方法, 在類裡面會生成和lambad 表達式參數和返回值完全匹配的方法.

匿名類

有時候,可以需要創建一個臨時的類對象,保存數據,方便使用。
一個普通的類對象


  public class Student
  {
      public int Id { get; set; }
      public int ClassId { get; set; }

      public string Name { get; set; }

      public int Age { get; set; }

      public string Description { get; set; }

      public void Study()
      {
          Console.WriteLine($"{this.Id} {this.Name} 跟著老師學習 .Net開發");

      }

      public void StudyQt()
      {
          Console.WriteLine($"{this.Id} {this.Name} 跟著老師學習C++ Qt");
      }
  }

當創建一個普通的類對象的時候,這樣去創建一個類對象。

 Student student = new Student()
 {
     Id = 1,
     ClassId = 2,
     Name = "張三",
     Age = 20,
     Description = "這是一個學生"
 };

現在嘗試最原始的方法去創建一個匿名類,

object model = new
{
    Id = 1,
    Name = "小樓一夜聽春雨",
    Age = 14,
    Description = "魔刀丁鵬"
};

為什麼可以定義一個匿名的對象?

因為C#中所有的對象都繼承自Object對象.

當嘗試使用.去訪問其中的屬性就會報錯.

C#是強類型語言(編譯時決定類型),object是在編譯時確定類型,因為Object沒有Id等屬性,所以無法通過.去訪問其中的變數.

因此可以使用下麵的方法去訪問我們的匿名對象中的屬性.

 dynamic model1 = new
 {
     Id = 2,
     Name = "天下第一的劍客",
     Age = 18,
     Description = "神劍山莊謝曉峰"
 };

 Console.WriteLine(model1.Id);
 Console.WriteLine(model1.Age);
 Console.WriteLine(model1.Amy); //報錯

這裡使用了dynamic關鍵字去避開了編譯器的檢查,會在運行時檢查,運行時決定類型.這個出現亂取的問題,導致程式崩潰.

有什麼方法可以正確的取出想訪問的屬性,又可以避免訪問不存在的屬性那?
var關鍵字

  var model2 = new
  {
      Id = 3,
      Name = "天下第二的劍客",
      Age = 16,
      Description = "不會劍法的阿飛"
  };

  Console.WriteLine(model2.Id);
  Console.WriteLine(model2.Name);
  //Console.WriteLine(model2.Aniu); //報錯!無法訪問不存在的變數

var類型就是弱類型的變數.

使用的註意事項?

  1. 不能在匿名類裡面聲明方法,同時在聲明匿名類的屬性時候,就給定匿名類的屬性初始值.
  2. 不能給屬性重新賦值.
  3. var聲明的變數必須初始化,必須能推算出類型,也不允許作為方法的參數類型.

使用的建議?

  1. var配合匿名類型使用
  2. var偷懶,配合複雜類型時使用。
  3. 在不知道具體什麼類型的時候就可以使用var來聲明

缺陷

在代碼閱讀的時候,不是很方便。

建議在大家寫代碼的時候,儘量明確類型。

擴展方法

為什麼需要擴展方法?

  1. 擴展:讓功能變得更加強大,讓不存在功能存在. ---新增邏輯處理
  2. 已經存在方法,正常調用,擴展的東西不影響已經存在的方法
  3. 如果需求變更,需要支持另外的一個新的功能。

接著上面學生的用例,我們可以追加一些需求.

Student student1 = new Student()
{
    Id = 1,
    ClassId = 2,
    Name = "張三",
    Age = 20,
    Description = "這是一個學生"
};

student1.Study();
student1.StudyQt();

如果要增加一個需求--學習嵌入式---直接增加方法.
傳統的方式對原有的類進行結構上的修改.

期望:既可以增加新的功能,歷史代碼不變.直接增加類,在新的類中去完成.

這裡就可以使用擴展方法來完成需求.

 public static class MethodExtension
 {
     public static void StudyEmbedded(this Student student)
     {
         Console.WriteLine($"{student.Id} {student.Name} 跟著老師學習嵌入式開發");
     }
 }

program.cs

student.StudyEmbedded();

可以看到做的操作就是:

  1. 把類變成靜態類
  2. 把方法的第一個參數+this修飾

這樣就完成了一個擴展方法.靜態方法的調用--可以像實例方法一樣去調用.

不用修改原有的任何類中的類,可以新增功能;

有哪些場景?

  1. 有新的需求來的時候--擴展方法--保證歷史代碼功能
  2. 要應用第三方的DLL庫(提供的功能不完善,我們自己需要升級下----dll,不能修改原有的代碼)擴展方法
  3. 封裝幫助類庫
  4. asp.net core 中,到處都是擴展方法--框架的設計--最小化設計.提供一個最基本、最最最簡單的功能,提供給調用方.這種方式在使用的時候,如果想要增強功能,就可以擴展. 好處:
    1. 儘可能簡化代碼
    2. 靈活分配,需要就擴展什麼.按需擴展,不會有代碼冗餘.

這裡有個問題,我可以給任意類型寫擴展方法嘛? 註意:擴展object類型.

 public static string SubObj(this object str, int len = 10)
 {
     if (str is null)
     {
         return string.Empty;
     }

     if (str.ToString().Length <= 10)
     {
         return str.ToString();
     }
     else
     {
         str = $"{str.ToString().Substring(0, len)}....";
         return str.ToString();
     }

 }

program.cs

 object o = "object 類型";
 o.SubObj();
  
 int i = 1;
 i.SubObj();//可以

 string sr = "你好";
 sr.SubObj();


 str.SubGeneric();
 student.SubGeneric(); //隱患

總結:

  1. 擴展的類型具有繼承性,擴展父類,所有子類都擁有這個功能;擴展的功能可能不適用一些具體的類型;但是仍然可以調用;可以造成一些類型的功能的污染;----慎用
  2. 不建議擴展object,也不是很建議大家去泛型擴展.

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

-Advertisement-
Play Games
更多相關文章
  • 這個作業屬於哪個課程 軟體工程2024 這個作業要求在哪裡 個人項目 這個作業的目標 瞭解軟體項目開發的整體流程,實現自己的個人項目,學習單元測試、性能優化和 git 操作,學會使用 PSP 表格 Github地址 : 點擊此處,進入我的倉庫 一、項目需求 題目:論文查重 設計一個論文查重演算法,給出 ...
  • 大家好,我是R哥。 周末愉快呀,最近我在做 Java 面試輔導,也模擬面試了好些個學員,說說其中一個學員吧,一個工作 5 年的 Java 程式員,模擬面試,居然一個問題也不會。。 當晚模擬面試完,我的心情很複雜。 我之前做系統架構師,同時也是面試官,這些年,少說也面試過幾百上千人,不乏知識淵博、技能 ...
  • .NET 6 引入了 LoggerMessageAttribute 類型。 使用時,它會以source-generators的方式生成高性能的日誌記錄 API。 source-generators可在編譯代碼時,可以提供其他源代碼作為編譯的輸入。 LoggerMessageAttribute依賴於 ...
  • 概述:ValueStopwatch是.NET中輕量級計時器,用於高性能時間測量。作為值類型,避免了裝箱拆箱開銷,記憶體占用小。通過簡單的使用方法,輕鬆實現代碼塊執行時間測量,且相比Stopwatch更為高效。 在.NET中,ValueStopwatch是一個輕量級的計時器類,用於測量代碼塊的執行時間。 ...
  • 概述:`Directory.Packages.props`和`Directory.Build.props`是.NET項目中的配置文件,分別用於統一管理NuGet包引用和自定義MSBuild構建過程。它們提高瞭解決方案的可維護性,通過集中配置,簡化了項目文件,使團隊協作更一致,同時避免了在每個項目中重 ...
  • 示例項目:https://gitee.com/easyxaf/recharge-rules-engine-sample 前言 繼上一篇文章對規則引擎編輯器進行了初步介紹之後,本文將通過實際應用案例深入探討規則引擎編輯器的使用方法。編輯器的操作相對簡單,我們將重點放在RulesEngine的講解上。請 ...
  • 這是我本人自己寫的一個開源庫,現已經發佈到nuget,可以直接在vs的nuget包管理中搜索到,或者可以到nuget官網下載:https://www.nuget.org/packages/ZmjConvert/,也可以到我的個人網站上下載源碼:https://www.zhaimaojun.cn/P/ ...
  • .NET Aspire Preview 4 is now available! Here's a summary of what's new in this preview release:.NET Aspire Preview 4 現已推出!以下是此預覽版中新增內容的摘要: Podman Supp ...
一周排行
    -Advertisement-
    Play Games
  • C#TMS系統代碼-基礎頁面BaseCity學習 本人純新手,剛進公司跟領導報道,我說我是java全棧,他問我會不會C#,我說大學學過,他說這個TMS系統就給你來管了。外包已經把代碼給我了,這幾天先把增刪改查的代碼背一下,說不定後面就要趕鴨子上架了 Service頁面 //using => impo ...
  • 委托與事件 委托 委托的定義 委托是C#中的一種類型,用於存儲對方法的引用。它允許將方法作為參數傳遞給其他方法,實現回調、事件處理和動態調用等功能。通俗來講,就是委托包含方法的記憶體地址,方法匹配與委托相同的簽名,因此通過使用正確的參數類型來調用方法。 委托的特性 引用方法:委托允許存儲對方法的引用, ...
  • 前言 這幾天閑來沒事看看ABP vNext的文檔和源碼,關於關於依賴註入(屬性註入)這塊兒產生了興趣。 我們都知道。Volo.ABP 依賴註入容器使用了第三方組件Autofac實現的。有三種註入方式,構造函數註入和方法註入和屬性註入。 ABP的屬性註入原則參考如下: 這時候我就開始疑惑了,因為我知道 ...
  • C#TMS系統代碼-業務頁面ShippingNotice學習 學一個業務頁面,ok,領導開完會就被裁掉了,很突然啊,他收拾東西的時候我還以為他要旅游提前請假了,還在尋思為什麼回家連自己買的幾箱飲料都要叫跑腿帶走,怕被偷嗎?還好我在他開會之前拿了兩瓶芬達 感覺感覺前面的BaseCity差不太多,這邊的 ...
  • 概述:在C#中,通過`Expression`類、`AndAlso`和`OrElse`方法可組合兩個`Expression<Func<T, bool>>`,實現多條件動態查詢。通過創建表達式樹,可輕鬆構建複雜的查詢條件。 在C#中,可以使用AndAlso和OrElse方法組合兩個Expression< ...
  • 閑來無聊在我的Biwen.QuickApi中實現一下極簡的事件匯流排,其實代碼還是蠻簡單的,對於初學者可能有些幫助 就貼出來,有什麼不足的地方也歡迎板磚交流~ 首先定義一個事件約定的空介面 public interface IEvent{} 然後定義事件訂閱者介面 public interface I ...
  • 1. 案例 成某三甲醫預約系統, 該項目在2024年初進行上線測試,在正常運行了兩天後,業務系統報錯:The connection pool has been exhausted, either raise MaxPoolSize (currently 800) or Timeout (curren ...
  • 背景 我們有些工具在 Web 版中已經有了很好的實踐,而在 WPF 中重新開發也是一種費時費力的操作,那麼直接集成則是最省事省力的方法了。 思路解釋 為什麼要使用 WPF?莫問為什麼,老 C# 開發的堅持,另外因為 Windows 上已經裝了 Webview2/edge 整體打包比 electron ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...