前言
1、天真熱,程式設計師活著不易,星期天,也要頂著火辣辣的太陽,總結這些東西。
2、誇誇lambda吧:簡化了匿名委託的使用,讓你讓程式碼更加簡潔,優雅。據說它是微軟自c#1.0後新增的最重要的功能之一。
lambda簡介
lambda運算子:所有的lambda表示式都是用新的lambda運算子 " => ",可以叫他,“轉到”或者 “成為”。運算子將表示式分為兩部分,左邊指定輸入引數,右邊是lambda的主體。
lambda表示式:
1.一個引數:param=>expr
2.多個引數:(param-list)=>expr
上面這些東西,記著,下面我們開始應用並闡述lambda,讓你樂在其中。
lambda應用闡述
闡述這技術,我先上一個例子,然後再慢慢深入分析。例子如下:
namespace 闡述lambda { public class Person { public string Name { get; set; } public int Age { get;set; } } class Program { public static List<Person> PersonsList() { List<Person> persons = new List<Person>(); for (int i = 0; i < 7; i++) { Person p = new Person() { Name = i + "兒子", Age = 8 - i, }; persons.Add(p); } return persons; } static void Main(string[] args) { List<Person> persons = PersonsList(); persons = persons.Where(p => p.Age > 6).ToList(); //所有Age>6的Person的集合 Person per = persons.SingleOrDefault(p => p.Age == 1); //Age=1的單個people類 persons = persons.Where(p => p.Name.Contains("兒子")).ToList(); //所有Name包含兒子的Person的集合 } } }
看啦上面的例子,相信你能看出它確實是個甜棗,呵呵,下面我們來看下(p=>p.Age>6)這樣的表示式,到底是怎麼回事。。
首先我們看下委託
//委託 逛超市 delegate int GuangChaoshi(int a); static void Main(string[] args) { GuangChaoshi gwl = JieZhang; Console.WriteLine(gwl(10) + ""); //列印20,委託的應用 Console.ReadKey(); } //結賬 public static int JieZhang(int a) { return a + 10; }
再看錶達式
//委託 逛超市 delegate int GuangChaoshi(int a); static void Main(string[] args) { // GuangChaoshi gwl = JieZhang; GuangChaoshi gwl = p => p + 10; Console.WriteLine(gwl(10) + ""); //列印20,表示式的應用 Console.ReadKey(); }
委託跟表示式的兩段程式碼,我們可以看出一些東東吧:其實表示式(p => p + 10;)中的 p 就代表委託方法中的引數,而表示式符號右邊的 p+10,就是委託方法中的返回結果。 大俠繞道,小蝦理解下。
下面再上兩個稍微複雜點的理解理解。
1.多引數的
//委託 逛超市 delegate int GuangChaoshi(int a,int b); static void Main(string[] args) { GuangChaoshi gwl = (p,z) => z-(p + 10); Console.WriteLine(gwl(10,100) + ""); //列印80,z對應引數b,p對應引數a Console.ReadKey(); }
2. lambda主體運算複雜
/// <summary> /// 委託 逛超市 /// </summary> /// <param name="a">花費</param> /// <param name="b">付錢</param> /// <returns>找零</returns> delegate int GuangChaoshi(int a,int b); static void Main(string[] args) { GuangChaoshi gwl = (p, z) => { int zuidixiaofei = 10; if (p < zuidixiaofei) { return 100; } else { return z - p - 10; } }; Console.WriteLine(gwl(10,100) + ""); //列印80,z對應引數b,p對應引數a Console.ReadKey(); }
上面這些例子,好好理解下,下面我要介紹一個系統指定的 Fun<T>委託。
Func<T>委託
T 是引數型別,這是一個泛型型別的委託,用起來很方便的。
先上例子
static void Main(string[] args) { Func<int, string> gwl = p => p + 10 + "--返回型別為string"; Console.WriteLine(gwl(10) + ""); //列印‘20--返回型別為string’,z對應引數b,p對應引數a Console.ReadKey(); }
說明:我們可以看到,這裡的p為int 型別引數, 然而lambda主體返回的是string型別的。
再上一個例子
static void Main(string[] args) { Func<int, int, bool> gwl = (p, j) => { if (p + j == 10) { return true; } return false; }; Console.WriteLine(gwl(5,5) + ""); //列印‘True’,z對應引數b,p對應引數a Console.ReadKey(); }
說明:從這個例子,我們能看到,p為int型別,j為int型別,返回值為bool型別。
看完上面兩個例子,相信大家應該明白啦Func<T>的用法:多個引數,前面的為委託方法的引數,最後一個引數,為委託方法的返回型別。
lambda表示式樹動態建立方法
static void Main(string[] args) { //i*j+w*x ParameterExpression a = Expression.Parameter(typeof(int),"i"); //建立一個表示式樹中的引數,作為一個節點,這裡是最下層的節點 ParameterExpression b = Expression.Parameter(typeof(int),"j"); BinaryExpression be = Expression.Multiply(a,b); //這裡i*j,生成表示式樹中的一個節點,比上面節點高一級 ParameterExpression c = Expression.Parameter(typeof(int), "w"); ParameterExpression d = Expression.Parameter(typeof(int), "x"); BinaryExpression be1 = Expression.Multiply(c, d); BinaryExpression su = Expression.Add(be,be1); //運算兩個中級節點,產生終結點 Expression<Func<int, int, int, int, int>> lambda = Expression.Lambda<Func<int, int, int, int, int>>(su,a,b,c,d); Console.WriteLine(lambda + ""); //列印‘(i,j,w,x)=>((i*j)+(w*x))’,z對應引數b,p對應引數a Func<int, int, int, int, int> f= lambda.Compile(); //將表示式樹描述的lambda表示式,編譯為可執行程式碼,並生成該lambda表示式的委託; Console.WriteLine(f(1, 1, 1, 1) + ""); //列印2 Console.ReadKey(); }
這段程式碼,放上來,仔細理解下,理解透徹啦,lambda表示式基本上也沒什麼啦。呵呵。。
算啦,我還是畫個圖算是結尾吧,以便於理解。
上段程式碼的lambda表示式樹,圖。