自C#3.0开始,就可以使用一种新语法把实现代码赋予委托:Lambda表达式。只要有委托参数类型的地方,就可以使用Lambda表达式。
Lambda表达式的语法比匿名方法简单。如果所调用的方法有参数,且不需要参数,匿名方法的语法就比较简单,因为这样不需要提供参数。
直接上一些例子,读者可以自行运行调试。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<code>static</code> <code>void</code> <code>Main(</code><code>string</code><code>[] args)</code>
<code>{</code>
<code> </code><code>//1、lambda之hello world.</code>
<code> </code><code>Func<</code><code>string</code><code>, </code><code>string</code><code>> lambda = param =></code>
<code> </code><code>{</code>
<code> </code><code>return</code> <code>param;</code>
<code> </code><code>};</code>
<code> </code>
<code> </code><code>Console.WriteLine(lambda(</code><code>"hello lambda."</code><code>));</code>
<code> </code><code>//2、lambda之参数</code>
<code> </code><code>Func<</code><code>double</code><code>, </code><code>double</code><code>, </code><code>double</code><code>, </code><code>double</code><code>> cube = (</code><code>double</code> <code>x, </code><code>double</code> <code>y, </code><code>double</code> <code>z) => x * y * z;</code>
<code> </code><code>Console.WriteLine(cube(1, 2, 3));</code><code>//输出6</code>
<code> </code><code>//更进一步,参数的类型可以省略</code>
<code> </code><code>Func<</code><code>double</code><code>, </code><code>double</code><code>, </code><code>double</code><code>, </code><code>double</code><code>> cude1 = (x, y, z) => x * y * z;</code>
<code> </code><code>Console.WriteLine(cude1(2, 4, 6));</code><code>//输出48</code>
<code> </code><code>//3、lambda之调用外部参数</code>
<code> </code><code>int</code> <code>someValue = 4;</code>
<code> </code><code>Func<</code><code>double</code><code>, </code><code>double</code><code>, </code><code>double</code><code>, </code><code>double</code><code>> f = (x, y, z) => x + y + z + someValue;</code>
<code> </code><code>Console.WriteLine(f(1, 2, 3));</code><code>//1+2+3+4=10</code>
<code>}</code>
在winform编程中,我们经常给某个按钮添加Click事件,最原始的写法是直接双击按钮,生成Click事件的代码,我们就可以直接在里面写方法了。其实这是vs替我们做了很多工作,其中就有在designer.cs文件中,生成了 this.button1.Click += new System.EventHandler(this.button1_Click);这样的代码,事件要注册才能触发。
我们采用匿名委托的写法,在窗体的Form_Load事件中添加如下代码,则可以触发button1的Click事件。
<code>this</code><code>.button1.Click += </code><code>delegate</code><code>(</code><code>object</code> <code>ss, EventArgs ee)</code>
<code> </code><code>MessageBox.Show(</code><code>"hello,this is button1.Click event..."</code><code>);</code>
<code>};</code>
再看看Lambda表达式的用法。
<code>this</code><code>.button1.Click += (ss, ee) =></code>
是不是更加简洁?
我们再看一下,从匿名方法到Lambda简写的演化过程,借一张图。

从这个演化过程,可以看出C#语言的发展变化过程。
下面详细演示一下Lambda的应用实例。
首先第一个实例我们应用Lambda对一个List<Student>列表进行循环、查找、排序等操作。
首先我们提供一个实体类:
<code>public</code> <code>class</code> <code>Student</code>
<code> </code><code>public</code> <code>Student(</code><code>string</code> <code>name, </code><code>int</code> <code>age)</code>
<code> </code><code>this</code><code>.Name = name;</code>
<code> </code><code>this</code><code>.Age = age;</code>
<code> </code><code>}</code>
<code> </code>
<code> </code><code>public</code> <code>string</code> <code>Name { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
<code> </code><code>public</code> <code>int</code> <code>Age { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
然后我们初始化一个List,
<code>//初始化3个Student对象</code>
<code>var</code> <code>students = </code><code>new</code> <code>List<Student>()</code>
<code> </code><code>new</code> <code>Student(</code><code>"zhang3"</code><code>,18),</code>
<code> </code><code>new</code> <code>Student(</code><code>"li4"</code><code>,22),</code>
<code> </code><code>new</code> <code>Student(</code><code>"wang5"</code><code>,20)</code>
<code>//定义1个打印函数</code>
<code>Action<Student> print = student => Console.WriteLine(</code><code>string</code><code>.Concat(student.Name, </code><code>":"</code><code>, student.Age));</code>
那么,我们就可以先循环输出一下:
<code>students.ForEach(print);</code><code>//循环打印输出</code>
如果我们要找到年龄大于20岁的学生,可以这样:
<code>students.FindAll(student => student.Age > 20).ForEach(print);</code>
进一步,我们按照学生的年龄进行排序:
<code>students.Sort((f1, f2) => f1.Age.CompareTo(f2.Age));</code>
<code>students.ForEach(print);</code><code>//年龄从小到大排序后输出</code>
现在,我们按照在students列表里再加一个学生:
<code> </code><code>new</code> <code>Student(</code><code>"wang5"</code><code>,20),</code>
<code> </code><code>new</code> <code>Student(</code><code>"zhao6"</code><code>,20)</code>
现在要按照年龄进行分组,并统计出各个年龄阶段的人数:
<code>var</code> <code>result = students.GroupBy(x => x.Age).Select(x => </code><code>string</code><code>.Concat(x.Key, </code><code>":"</code><code>, x.Count()));</code><code>//先进行分组,再进行投影</code>
<code>result.ToList().ForEach(x => Console.WriteLine(x.ToString()));</code><code>//循环输出得到结果</code>
再提供一个综合性的例子,这是论坛里的caozhy版主提供的一个例子。用Lambda表达式实现快速排序。
<code>Func<Func<</code><code>int</code><code>, </code><code>int</code><code>, </code><code>bool</code><code>>, Func<</code><code>int</code><code>[], </code><code>int</code><code>[]>> filter = x => </code><code>new</code> <code>Func<</code><code>int</code><code>[], </code><code>int</code><code>[]>(y => y.Skip(1).Where(z => x(y[0], z)).ToArray());</code>
<code>Func<</code><code>int</code><code>[], </code><code>int</code><code>[]> qsort = x => x;</code>
<code>Func<</code><code>int</code><code>[], </code><code>int</code><code>[]> lesser = dt => filter((x, y) => y < x)(dt);</code>
<code>Func<</code><code>int</code><code>[], </code><code>int</code><code>[]> greater = dt => filter((x, y) => y >= x)(dt);</code>
<code> </code>
<code>qsort = dt => dt.Length > 1</code>
<code> </code><code>? qsort(lesser(dt)).Concat(</code><code>new</code> <code>int</code><code>[] { dt[0] }).Concat(qsort(greater(dt))).ToArray() : dt;</code>
<code>int</code><code>[] data = { 4, 3, 1, 4, 6, 7, 5, 9, 3, 11, 1, 2, 11 };</code>
<code>var</code> <code>result = qsort(data);</code>
<code>result.ToList().ForEach(x => Console.WriteLine(x.ToString()));</code><code>//排完序后输出</code>
本文转自 guwei4037 51CTO博客,原文链接:http://blog.51cto.com/csharper/1344193