程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 委托、Lambda表達式、事件系列03,從委托到Lamda表達式,lambdalamda

委托、Lambda表達式、事件系列03,從委托到Lamda表達式,lambdalamda

編輯:C#入門知識

委托、Lambda表達式、事件系列03,從委托到Lamda表達式,lambdalamda


在"委托、Lambda表達式、事件系列02,什麼時候該用委托"一文中,使用委托讓代碼簡潔了不少。

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類型。

 

其實,lambda表達式n => n < 5是一種"語法糖",內部還是執行了如下代碼:

        ......
        MyCalculateDelegate del = LessThanFive;
        var result = GetNumbers(source, del);
        ......
        static bool LessThanFive(int val)
        {
            return val < 5;
        }


這一點可以從IL層面看出。使用Reflector進行反編譯:

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方法是由編譯器幫我們自動生成的。

 

總結:lambda表達式其實是"語法糖",源代碼被編譯的時候,編譯器會自動幫我們生成一個符合委托定義的方法,然後把該方法賦給委托。

 

 

“委托、Lambda表達式、事件系列”包括:

委托、Lambda表達式、事件系列01,委托是什麼,委托的基本用法,委托的Method和Target屬性

委托、Lambda表達式、事件系列02,什麼時候該用委托

委托、Lambda表達式、事件系列03,從委托到Lamda表達式


什是lamda表達式?

msdn.microsoft.com/zh-cn/library/bb397687.aspx

升級版的匿名委托
比較強悍

“Lambda 表達式”是一個匿名函數,它可以包含表達式和語句,並且可用於創建委托或表達式目錄樹類型。

所有 Lambda 表達式都使用 Lambda 運算符 =>,該運算符讀為“goes to”。該 Lambda 運算符的左邊是輸入參數(如果有),右邊包含表達式或語句塊。Lambda 表達式 x => x * x 讀作“x goes to x times x”。可以將此表達式分配給委托類型
 

lambda表達式不懂,舉個簡單的例子,再解釋一下,

最大的作用是用在匿名函數和linq查詢上。
這是用在匿名方法上的:
delegate int del(int i);
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
等價於
delegate int del(int i);
del myDelegate = delegate(int i){i=i*i;};
int j = myDelegate(5); //j = 25
至於linq前景不明,就不要深究了。

直接i+1???
呵呵,你是沒碰到一些必須用委托的情況。
比如跨線程調用,你只能用委托,而lambda表達式就是一個很方便的寫法。純粹為了方便而已。
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved