LINQ学前准备之Lambda Expressions
Lambda表达式是C#3.0引进来的语法。Lambda表达式提供了匿名方法的备选方案。虽然Lambda主要用于LINQ操作,但是这种表达式也适用于,并且经常用于委托和事件。
Lambda运算符
Lambda采用了全新的运算符”=>”,”=>”为二元运算符,左边是输入参数,右边是Lambda主体。”=>”可描述成”转到”或“成为”.
如
x=>x
可读成x goes to x或input x return x
让我们通过一个例子来看看命名方法、匿名方法、Lambda表达式的不同写法。
假设我们有一个Int的数组,需要根据不同的过滤规则来返回所需要的数组。
命名方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public class Common { public delegate bool IntFilter( int i); //声明一个命名委托 public static int [] FilterArrayOfInt( int [] ints, IntFilter filter) //传入委托 { ArrayList alist = new ArrayList(); foreach ( int i in ints) { if (filter(i)) { alist.Add(i); } } return ( int [])alist.ToArray( typeof ( int )); } } |
1 | |
1 | 此时,我们还需要新建一些IntFilter的类: |
1 2 3 4 5 6 7 | public class Application { public static bool IsOdd( int i) { return ((i & 1) == 1); } } |
1 | |
1 | 客户端调用: |
1 2 3 4 5 | using System.Collections; int [] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int [] oddNums = Common.FilterArrayOfInts(nums, Application.IsOdd); foreach ( int i in oddNums) Console.WriteLine(i); |
当我们需要不同的filter的时候,我们需要新建一系列类似于Application.IsOdd的方法。
匿名方法
像上面的Application.IsOdd方法其实只会被客户端调用一次,同时,我们创建一系列的Application.IsOdd也挺烦的,要维护一系列的类。
C# 2.0引入了匿名方法,匿名方法允许我们不需要创建类似Application.IsOdd方法,而是在需要传入委托方法的时候直接传入一个匿名的方法。
1 2 3 4 5 | int [] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int [] oddNums = Common.FilterArrayOfInts(nums, delegate ( int i) { return ((i & 1) == 1); }); foreach ( int i in oddNums) Console.WriteLine(i); |
1 | |
1 | 采用这种方法,我们可以不需要再定义多余的Filter类。但是,这种方法的可读性比较差。 |
1 | |
1 | <strong>Lambda表达式</strong> |
1 | |
1 2 3 4 | int [] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int [] oddNums = Common.FilterArrayOfInts(nums, i => ((i & 1) == 1)); foreach ( int i in oddNums) Console.WriteLine(i); |
以下就是三种方式的具体差别:
1 2 3 4 5 6 7 8 | int [] oddNums = // using named method Common.FilterArrayOfInts(nums, Application.IsOdd); int [] oddNums = // using anonymous method Common.FilterArrayOfInts(nums, delegate ( int i){ return ((i & 1) == 1);}); int [] oddNums = // using lambda expression Common.FilterArrayOfInts(nums, i => ((i & 1) == 1)); |
1 | |
1 | 命名方法适用于当你的Filter需要可被重复使用的时候。而Lambda提供了更灵活的方式。 |
1 | |
1 | |
1 | <strong>Lambda表达式描述</strong> |
1 | 当Lambda表达式只有一个参数时,其通用形式为: |
1 | <em>param=>expr</em> |
1 | |
1 | 当Lambda表达式需要多个参数时,其通用形式为: |
1 | <em>(param-list)=>expr</em> |
1 | |
1 | <u>Note:当参数多余一个的时候,参数列表需要包括在圆括号里面。</u> |
1 | <u></u> |
1 | 对于上面的例子,i => ((i & 1) == 1)我们可能会困惑,编译器如何知道参数及表达式的类型的呢? |
1 | 答案是:编译器根据FilterArrayOfInts需要的委托类型(在这个例子中,为IntFilter,他有一个 int 的输入参数,同时返回 bool 类型的值)来推断参数的类型和表达式的返回类型。 |
1 | 因此,很重要的一点是:Lambda的参数和返回值类型必须与委托的参数类型和返回值类型相匹配。 |
1 | |
1 | 参考书目:Pro.LINQ.Language.Integrated.Query. in .Csharp.2010 |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步