1. 程式人生 > 其它 >C#筆記(四):Lambda 表示式

C#筆記(四):Lambda 表示式

最近實習早出晚歸很累,一直沒有更新!額,基礎還是要鞏固的!

匿名函式

在學習委託時,有個概念叫做匿名函式:即不需要在外部定義方法,直接在初始化委託時申明方法。先來看一個例子。

    class Program
    {
        static void Main(string[] args)
        {
            //ad指向匿名函式
            //delegate(引數列表){方法體}
            AnonyDelegate ad = delegate(string str)
            {
                Console.WriteLine(str);
            };
            //呼叫委託
            ad("Hello World");
            Console.ReadKey();
        }
        //申明委託
        public delegate void AnonyDelegate(string s);
    }

其實在呼叫時,匿名函式的引數的列表型別必須對應定義委託的引數列表型別,每次都需要自己去手動寫。那麼,能不能有一種方法能讓編譯器自動推斷委託的引數列表型別呢?此時,Lambda 表示式就可以幫助我們處理這個問題了。

使用Lambda表示式:

        static void Main(string[] args)
        {
            //能夠根據委託推斷出引數的列表型別,比匿名函式更簡單
            AnonyDelegate ad = (str) =>{ Console.WriteLine(str); };
            //呼叫委託
            ad("Hello World");
            Console.ReadKey();
        }
        //申明委託
        public delegate void AnonyDelegate(string s);

Lambda表示式

對於Lambda表示式的一些介紹,msdn也講得挺清晰的。

"Lambda表示式"是一個匿名函式,它可以包含表示式和語句,並且可用於建立委託或表示式樹型別。

所有 Lambda 表示式都使用 Lambda 運算子=>,該運算子讀為"goes to"。該 Lambda 運算子的左邊是輸入引數(如果有),右邊包含表示式或語句塊。Lambda 表示式x => x * x讀作"x goes to x times x"。這句話可以簡單的總結為Lambda 表示式的語法結構:

(輸入引數)=> 表示式

注意點:

(1)當Lambda 只有一個輸入引數時,可以省略括號,但其他情況是必須要加的。

            //當只有一個輸入引數時,可以省略括號
            AnonyDelegate ad = str =>{ Console.WriteLine(str); };

(2)當只有一個空的括號時,表示沒有引數。

            AnonyDelegate2 ad2 = () => { Console.WriteLine("Hello World"); };
           //申明委託
            public delegate void AnonyDelegate2();

(3)當lambda表示式中的匿名函式的方法體如果只有一句話,並且是返回值,那麼可以省略{}以及return,就把=>後的表示式做為返回值

        //申明委託
        public delegate bool AnonyDelegate3(string str);
        AnonyDelegate3 ad3 = (str) => str == "Hello World";
        Console.WriteLine(ad3("Hello World"));

Lambda表示式使用場景

這一塊內容相對比較重要,Lambda表示式現在應用很廣,例如查詢表示式,所以需要掌握這個基礎知識。

Lambda 在基於方法的 LINQ 查詢中用作標準查詢運算子方法(如Where等)的引數。

使用基於方法的語法在Enumerable類中呼叫Where方法時(像在 LINQ to Objects),引數是委託型別System.Func<T, TResult>。使用 Lambda 表示式建立委託很方便。例如,當您在System.Linq.Queryable類中呼叫相同的方法時,則引數型別是System.Linq.Expressions.Expression<Func>,其中 Func 是包含至多十六個輸入引數的任何 Func 委託。同樣,Lambda 表示式只是一種用於構造表示式樹的非常簡練的方式。

使用Lambda表示式如何篩選陣列中大於0的數呢?其實非常簡單!

            int[] values = { -8, 2, 13, -5, 9 };
            IEnumerable<int> result = values.Where(s => s > 0);
            foreach (var val in result)
            {
                Console.WriteLine(val);
            }
            Console.ReadKey();

那麼為什麼直接可以使用該方法呢?我們轉到where的方法定義,可以看到

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);

Tsource:source中的元素的型別。這裡指int型別。

source:型別為System.Collections.Generic.IEnumerable<TSource>。要篩選的IEnumerable<T>。這裡指values陣列。

predicate:型別為System.Func<TSource,Boolean>。用於測試每個元素是否滿足條件的函式。這是指方法體的實現。

返回值:一個IEnumerable<T>,包含輸入序列中滿足條件的元素。這裡指返回IEnumerable<T>。

Func<TSource,bool> :實際上是泛型委託的Func<T, TResult>系列的其中之一。Func<T, TResult>委託使用型別引數定義輸入引數的數目和型別,以及委託的返回型別。這是指int為輸入引數,bool是返回型別。

同理其他的方法原理差不多。輕描淡寫,下階段再寫深入些的!

轉https://www.cnblogs.com/ForEvErNoME/archive/2012/08/21/2633767.html