首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

LINQ 學習筆記(二).NET 3.x 新特性回顧(五):Func/Action/Predicate、擴充方法、查詢語法與 IL 視角

     編輯:關於C語言

系統預定義泛型委派

.NET 3.5 內建三大委派家族,配合 Lambda 運算式極大簡化程式碼:

委派型別參數對應方法簽章用途
Func<TResult>最後一個為回傳型別TResult Method()有回傳值的運算
Func<T, TResult>前 N-1 為參數,最後為回傳TResult Method(T arg)轉換/投影
Action<T>參數型別void Method(T arg)執行動作(無回傳)
Predicate<T>參數型別bool Method(T arg)條件判斷/篩選

Lambda 編譯後的 IL 真相

以下 Lambda:

Func<string> f = () => "abc";

編譯器產生私有靜態方法:


.method private hidebysig static string '<Main>b__0'() cil managed
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
  .maxstack 1
  .locals init ([0] string CS$1$0000)
  IL_0000: nop
  IL_0001: ldstr "abc"
  IL_0006: stloc.0
  IL_0007: br.s IL_0009
  IL_0009: ldloc.0
  IL_000a: ret
}

本質上,Lambda 只是編譯器自動產生方法並包裝為委派的語法糖。

擴充方法:為現有型別「無侵入式」新增行為

規則

  • 定義於 static 類別中
  • 方法為 static
  • 第一個參數加 this 修飾,指明擴充對象
  • 命名空間引入後即可像實例方法般呼叫

範例


public class Test1 { public string String1 { get; set; } public int Int1 { get; set; } }

public static class Test2
{
    public static string AddDefaultPage(this Test1 t)
    {
        return t.String1 + "/Default.ASPx";
    }
}

// 呼叫
var t4 = new Test1 { String1 = "https://xianfen.Net", Int1 = 0 };
t4.AddDefaultPage(); // 如同實例方法

IL 視角

擴充方法編譯為靜態方法呼叫:


.call string CS30NEW.Test2::AddDefaultPage(class CS30NEW.Test1)

若實例方法與擴充方法同名同簽章,實例方法優先。擴充方法無法存取 private/protected 成員。

查詢語法:LINQ 核心

查詢語法(from...where...select)編譯為擴充方法鏈結,最終皆為 Enumerable 靜態方法呼叫。CLR 版本維持 2.0,所有魔法由編譯器完成。

結語

.NET 3.x 未變更 CLR/IL,純粹透過編譯器語法糖與框架擴充方法,賦予開發者更高表達力。理解其本質,有助於除錯、效能調優與進階擴充。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved