以前一直迷迷糊糊的,現在總算搞明白。
Lambda表達式
Lamda表達式基本寫法是()=>{ };
Lambda和方法一樣都可以傳入參數和擁有返回值。(int x)=>{return x;};
Lambda表達式並不是C#獨有的,其它語言也擁有Lambda表達式。
一些文檔上寫Lambda是匿名函數,我認為是不對的,Lambda可以表示一個匿名函數,但是還可以來表示Linq表達式啊。
delegate委托
委托基本的使用包括聲明一個委托、實例化一個委托、使用一個委托。
// 聲明一個委托,類型是myDelegate, public delegate void myDelegate(string str); public static void HellowChinese(string strChinese) { Console.WriteLine("Good morning," + strChinese); Console.ReadLine(); } // 實例化 myDelegate d = new myDelegate(HellowChinese); // 使用 d("Mr wang");
委托很好用。當編程到一定階段,發現只傳遞一個或幾個int、strig類型參數是不夠的,希望可以把一段代碼進行傳遞來執行某個操作,委托提供了這樣的途徑,委托提供了一種可以直接訪問類中方法的途徑,可以將方法當作一個參數傳遞從而使用。
匿名函數
上面已經講到匿名函數了。函數和方法等價,用來封裝一段代碼片以便隨時使用,有的有返回值有的無返回值。寫在類里面。
但是如果我只想把這段代碼片使用一次呢?再聲明一個類、一個方法實在太麻煩,這時候匿名函數就擁有了價值。用來封裝一段代碼、直接執行或者傳遞。
匿名函數總是和委托一齊使用,因為匿名函數方便了委托的使用(不用聲明一個類了)
匿名方法兩種實現方式:
使用Lambda表達式:
public delegate void Seep(); static void Main(string[] args) { Seep s = () => { Console.WriteLine(2); Console.WriteLine(1); }; }
使用委托
public delegate void Seep(); static void Main(string[] args) { Seep see = delegate () { Console.WriteLine(1); }; }
Action、Func、Predicate
委托需要先聲明一個類型才能使用,這很麻煩,比如我在某一個命名空間聲明了一個沒有返回值的委托myDelegate,然后想要這個委托的時候,每個命名空間都要引用這個命名空間,這太不友好了。
微軟直接就在框架中定義了三種委托:Action、Func、Predicate。這三種委托是C#的System命名空間中已經定義好的,如Action

上面已經通過匿名函數實現了不用聲明類,現在通過C#預定義的委托類型實現了不用聲明委托類型,那么現在就可以直接寫代碼片來執行了
這三種委托的相應泛型形式,可以寫出如下代碼:
#region 無參數無返回值 // lambda實現委托實例 Action a1 = () => Console.WriteLine(1); a1(); // delegate實現委托實例,下面不再演示delegate。 Action a2 = delegate { Console.WriteLine(1); }; a2(); #endregion #region 有參數無返回值 Action<int> a3 = (x) => Console.WriteLine(x); a3(1); #endregion #region 無參數有返回值的情況 Func<int> e1= ()=> 1; var value1= e1(); #endregion #region 有參數有返回值的情況 // 最后一個泛型是返回值的類型 Func<int,int> e2 = (x) => x+1; int value2= e2(1); // 多參數情況 Func<int, int,int> e3 = (x,x2) => x+x2 + 1; int value3 = e3(1,2); #endregion #region 返回值是布爾類型 // 其實Predicate可以用Func返回值是bool來代替的。 Predicate<int> p = (x) => x > 0; bool value4 = p(1); #endregion
委托還有一些特性(如可加性),感興趣的可以查閱相關資料。
Expression
Expression指的是System.Linq.Expressions,是Linq表達式,表達式樹,不是Lambda表達式!!
Linq表達式用於離線集合的查詢。什么是離線集合?最常用的是EF里面的DBContext,我也只用過這個,所以我不想那么多,就把Expression當成EF里面使用的就行了。
1、只能接受Lambda表達式表示的委托
2、Lambda表達式只能有一條語句。
Expression<Func<int,int>> eeee = (x)=> x+ 1 ;
總結
1、都是希望可以單獨引用一段代碼片引起的。
2、然后引用了委托delegate,delegate的使用方式為聲明類型-實例化類型(傳入想要使用的類的方法)-使用委托(使用方法)
3、簡化操作,使用(通過Lambda或者delegate)匿名方法來直接聲明一段代碼片,避免聲明所想使用的類的方法
4、簡化操作,直接使用C#預定義的三種委托Action、Func、Predicate,連聲明委托都省了。
5、本文代碼:https://github.com/Beiluola/delegateDemo
注意
1、匿名函數總是和委托一起使用(三種預定義委托)
2、使用三種預定義委托就可以滿足大多數需求。
3、Expression是Linq表達式樹,只能使用接受一句lambda表達式。和匿名函數無關。
