C#中委託,匿名方法,Lambda表達式之間的關係

都說C#是C語言版的Java,它是基於Java的基礎上,增加的更多的獨有的語言功能,而委託就是其中之一,而也就是委託讓我感覺到從Java轉到C#的一個大難點。
委託是通過delegate關鍵字來定義,簡單來說,委託是一個類,它定義了方法的類型,使得可以將方法當作另一個方法的參數來進行傳遞。這方面就有些相似於JavaScript的函數,它也是能夠將函數作爲參數進行傳遞。至於爲什麼要這麼做,其原理是觀察者設計模式,這裏我不做詳細說明。
進入正題,首先我先給出這三者之間的從屬關係:委託->匿名表達式->Lambda表達式
從關係式不難看出,Lambda表達式一定能夠轉化成匿名表達式和原始的委託方式,而匿名表達式也一定能夠轉換成原始的委託方式。
上代碼:

        / //定義委託類型
        delegate int calculator(int x, int y);
        static void Main(string[] args)
        {
            //初始化委託類型(命名方法),注意是add不是add()
            calculator add1 = new calculator(add);
            //匿名方法是通過使用 delegate 關鍵字創建委託實例來聲明的
            calculator add2 = delegate (int a, int b)
            {
                return a + b;
            };
            //任何 Lambda 表達式都可以轉換爲委託類型
            //表達式 lambda
            calculator add3 = (a, b) => a + b;
            //Func 類型:有任意返回值的委託類型,最後一個泛型是返回值類型
            Func<int, int, int> add4 = (a, b) => a + b;
            //給委託變量再綁定或者刪除一個方法
            add1 += sub;
            //add1 -= sub;
            //add1()只會輸出最近的那個函數的結果
            Console.WriteLine(add1(1, 6));
            Console.WriteLine(add2(2, 6));
            Console.WriteLine(add3(3, 6));
            Console.WriteLine(add4(4, 6));
        }
        private static int sub(int a, int b)
        {
            return 4 * a - b;
        }

        private static int add(int a, int b)
        {
            return 2 * a + b;
        }

上述代碼用4種方式實現一個加法功能:
第一種方式是最原始的委託使用方式,定義,聲明,初始化,調用。
第二種方式是匿名方法的形式,通過delegate關鍵字將所需要綁定的方法直接內部實現。
第三種方式是 Lambda 表達式,進一步簡化第二種方式的代碼,變得更加簡潔美觀。
第四種方式是調用 .NET Core 框架內部已有的委託類型,此方式實現可重用。(推薦的使用方式)

由於委託的參數是方法,所以也可以將多個方法賦給同一個委託,當調用這個委託的時候,將依次調用其所綁定的方法。
在 .NET Core 框架內部定義的常用委託類型有兩種:Action 類型與Func 類型
它倆都是泛型類型,只不過前者是具有 void 返回類型的委託類型,而後者是有任意返回值的委託類型。
在C#中Lambda 表達式具體來說也有多種類型,上述代碼的Lambda 表達式屬於表達式 lambda,基礎常用的還有語句Lambda和含標準查詢運算符的 lambda
上代碼:

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
            //匿名方法
            int oddNumbers1 = numbers.Count(delegate (int n)
            {
                return n % 2 == 0;
            });
            Console.WriteLine(oddNumbers1);
            //含標準查詢運算符的 lambda
            int oddNumbers2 = numbers.Count(n => n % 2 == 1);
            Console.WriteLine(oddNumbers2);
            //Action 類型:具有 void 返回類型的委託類型
            //匿名方法
            Action<int[], int, int> change1 = delegate (int[] nums, int a, int b)
              {
                  var tmp = nums[a];
                  nums[a] = nums[b];
                  nums[b] = tmp;
              };
            //語句Lambda
            Action<int[], int, int> change2 = (nums, a, b) =>
            {
                var tmp = nums[a];
                nums[a] = nums[b];
                nums[b] = tmp;
            };
            change1(numbers, 0, 1);
            change2(numbers, 2, 3);
            foreach (var item in numbers)
            {
                Console.Write(item + " ");
            }

相信經過上述兩個案例的對比代碼,這三者之間的關係應該就很容易理解了。
其實剛開始就想直接寫出Lambda的確挺難的,還是先從委託開始慢慢過渡到熟悉匿名函數,最後就能輕易的掌握Lambda表達式!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章