Lambda表達式是C#3.0的一種新語法,語法簡潔
為編寫匿名方法提供了更簡明的函數式的句法.
我通過一個示例來說明Lambda表達式的原理:
Lambda表達式和匿名方法都來源於委托
我們來看看委托的使用
在C#1.0時:
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6namespace ConsoleApplication3
7{
8 public delegate int Calculate(int a, int b);
9 class Program
10 {
11
12 static void Main(string[] args)
13 {
14 int a = 3;
15 int b = 4;
16 Calculate result = new Calculate(Add);
17 Console.WriteLine(result(a,b));
18 Console.Read();
19 }
20
21 public static int Add(int a, int b)
22 {
23 return a + b;
24 }
25 }
26}
27
C#2.0時可以使用匿名方法:
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6namespace ConsoleApplication3
7{
8 public delegate int Calculate(int a, int b);
9 class Program
10 {
11
12 static void Main(string[] args)
13 {
14 int a = 3;
15 int b = 4;
16 Calculate result = delegate(int ta, int tb) { return ta + tb; };
17
18 Console.WriteLine(result(a,b));
19 Console.Read();
20 }
21
22 }
23}
24
C#3.0使用Lambda表達式:
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6namespace ConsoleApplication3
7{
8 public delegate int Calculate(int a, int b);
9 class Program
10 {
11
12 static void Main(string[] args)
13 {
14 int a = 3;
15 int b = 4;
16 Calculate result = (ta, tb) => ta + tb;
17 Console.WriteLine(result(a,b));
18 Console.Read();
19 }
20
21 }
22}
23
使用Lambda表達式更簡潔,為什麼那麼簡潔.其實是編譯器為我們做了很多事情.
Calculate result = (ta, tb) => ta + tb;
這句話 編譯器在編譯的時候 會為我們生成一個私有的靜態方法.透過ILDASM可以看到它是怎麼幫助我 們的,
編譯器為我們聲明聲明了一個私有靜態的Calculate委托字段 和一個靜態的私有方法.
通過IL代碼可以看看Main方法內部是怎麼實現的
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// 代碼大小 58 (0x3a)
.maxstack 3
.locals init ([0] int32 a,
[1] int32 b,
[2] class ConsoleApplication3.Calculate result)
IL_0000: nop
IL_0001: ldc.i4.3
IL_0002: stloc.0
IL_0003: ldc.i4.4
IL_0004: stloc.1
IL_0005: ldsfld class ConsoleApplication3.Calculate ConsoleApplication3.Program::'CS$<>9__CachedAnonymousMethodDelegate1'
IL_000a: brtrue.s IL_001f
IL_000c: ldnull
IL_000d: ldftn int32 ConsoleApplication3.Program::'<Main>b__0'(int32,
int32)
IL_0013: newobj instance void ConsoleApplication3.Calculate::.ctor(object,
native int)
IL_0018: stsfld class ConsoleApplication3.Calculate ConsoleApplication3.Program::'CS$<>9__CachedAnonymousMethodDelegate1'
IL_001d: br.s IL_001f
IL_001f: ldsfld class ConsoleApplication3.Calculate ConsoleApplication3.Program::'CS$<>9__CachedAnonymousMethodDelegate1'
IL_0024: stloc.2
IL_0025: ldloc.2
IL_0026: ldloc.0
IL_0027: ldloc.1
IL_0028: callvirt instance int32 ConsoleApplication3.Calculate::Invoke(int32,
int32)
IL_002d: call void [mscorlib]System.Console::WriteLine(int32)
IL_0032: nop
IL_0033: call int32 [mscorlib]System.Console::Read()
IL_0038: pop
IL_0039: ret
} // end of method Program::Main
可以看出IL_0005: 到IL_001f 這段代碼是初始化編譯器為我們生成的委托
下面幾行IL指令可以看出來是為我們初始化委托
IL_000c: ldnull //聲明一個空的函數指針
IL_000d: ldftn //加載方法指針 指向 '<Main>b__0'(int32,int32) 函數
IL_0013: newobj //實例化委托
IL_0018: stsfld //保存
透過IL代碼 我們看到了Lambda表達式的的正真實現方法….
看到了C#語言沒有什麼改變 只是編譯器為我們完成了很多東西