在"委託、Lambda表達式、事件系列02,何時該用委託"一文中,使用委託讓代碼簡潔了很多。
html
namespace ConsoleApplication2
{internal delegate bool MyCalculateDelegate(int val);class Program
{static void Main(string[] args){IEnumerable<int> source = new List<int>(){2, 3, 4, 5, 6, 7, 8, 9,10, 11};MyCalculateDelegate del = LessThanFive;var result = GetNumbers(source, del);foreach (int n in result){Console.WriteLine(n);}}static IEnumerable<int> GetNumbers(IEnumerable<int> numbers, MyCalculateDelegate del){foreach (int number in numbers){if (del(number)) yield return number;}}static bool LessThanFive(int val){return val < 5;
}static bool LessThanTen(int val){return val < 10;
}}}
但是,以上LessThanFive方法和LessThanTen方法的輸入參數、輸出類型、以及實現邏輯都是一致的,有沒有一種形式能夠替代它們?這正是Lambda表達式登場的時候!Lambda表達式是匿名委託,以=>分隔,左邊是輸入參數,右邊是實現過程。閉包
namespace ConsoleApplication2
{internal delegate bool MyCalculateDelegate(int val);class Program
{static void Main(string[] args){IEnumerable<int> source = new List<int>(){2, 3, 4, 5, 6, 7, 8, 9,10, 11};var result = GetNumbers(source, n => n < 5);foreach (int n in result){Console.WriteLine(n);}}static IEnumerable<int> GetNumbers(IEnumerable<int> numbers, MyCalculateDelegate del){foreach (int number in numbers){if (del(number)) yield return number;}}}}
以上,使用Lambda表達式又讓代碼簡潔了很多!GetNumbers的實參n => n < 5,就是一個Lambda表達式,它符合委託MyCalculateDelegate的定義,輸入參數是整型,輸出是bool類型。spa
其實,lambda表達式n => n < 5是一種"語法糖",內部仍是執行了以下代碼:htm
......MyCalculateDelegate del = LessThanFive;var result = GetNumbers(source, del);......static bool LessThanFive(int val){return val < 5;
}
這一點能夠從IL層面看出。使用Reflector進行反編譯:blog
private static void Main(string[] args){List<int> <>g__initLocal0 = new List<int>();<>g__initLocal0.Add(2);<>g__initLocal0.Add(3);<>g__initLocal0.Add(4);<>g__initLocal0.Add(5);<>g__initLocal0.Add(6);<>g__initLocal0.Add(7);<>g__initLocal0.Add(8);<>g__initLocal0.Add(9);<>g__initLocal0.Add(10);<>g__initLocal0.Add(11);IEnumerable<int> source = <>g__initLocal0;
IEnumerable<int> result = GetNumbers(source, (CS$<>9__CachedAnonymousMethodDelegate2 != null) ? CS$<>9__CachedAnonymousMethodDelegate2 : (CS$<>9__CachedAnonymousMethodDelegate2 = new MyCalculateDelegate(Program.<Main>b__1)));foreach (int n in result){Console.WriteLine(n);}}
以上,因爲n => n > 5符合委託MyCalculateDelegate的定義,在內部建立了一個MyCalculateDelegate類型的委託,而後把一個編譯器生成的方法<Main>b__1賦給了委託變量。事件
[CompilerGenerated]private static bool <Main>b__1(int n){return (n < 5);
}
<Main>b__1方法是由編譯器幫咱們自動生成的。get
總結:lambda表達式實際上是"語法糖",源代碼被編譯的時候,編譯器會自動幫咱們生成一個符合委託定義的方法,而後把該方法賦給委託。編譯器
「委託、Lambda表達式、事件系列」包括:string