简介
Lambda 是一种可用于创建委托或表达式目录树类型的匿名函数。通过使用 lambda 表达式,可以写入可作为参数传递或作为函数调用值返回的本地函数!
场景
比如有这样一个场景,在给出的List集合中找出数字大于等于18的数字,假如我们不知道有linq这种东西!
List<int> lstAges = new List<int> { 16,17,18,19,20 };
我们预定义了一个输出年龄的方法
void OutPutAge(Func<int,bool> func)
{
foreach (var item in lstAges)
{
if (func(item))
{
Console.WriteLine(item);
}
}
}
可以看出方法接收一个委托,该委托接收一个int类型的参数,并返回bool
那么我们首先会定义一个方法,当年龄大于18的时候我们返回true
bool IsAgeScrren(int age)
{
return age > 18;
}
使用
OutPutAge(IsAgeScrren);
比如说我们现在知道这个方法仅仅传递一个方法的引用,我们很确定这个方法只会调用这一次,单独为它创建一个方法感觉有些浪费,但是又必须用到这个方法,但是思考半天想不出该给这个方法取什么名字)。这个时候Lambda就派上用场了!
那么我们可以先简化成匿名方法
OutPutAge(delegate (int age) { return age > 18; });
现在我们把delegate关键字删掉,在参数列表和方法体之间使用=>箭头符号连接,这就形成了Lambda表达式
OutPutAge( (int age) =>{ return age > 18; });
在函数式的编程语言中,如果最后一句是return表达式的话,我们最后可以把return和{}这个关键字省掉
OutPutAge( (int age) =>( age > 18));
c#也有类型推断功能,我们在前面的 foreach (var item in lstAges)
这里c#可以自动推断出 age是int类型,所以我们也可以把int类型直接省掉
就变成了,这样看起来是不是就和我们平常的lambda表达式一样了
OutPutAge( age => age > 18);
那么我们再回到头来看,如果我们知道Linq语句中的where方法其实帮我们做了很多事
List<int> lstAges = new List<int> { 16,17,18,19,20 };
lstAges.Where(o => o > 18)
我们再看一下Where的定义
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
throw null;
}
他是使用了扩展方法和委托来完成的
source是 源元素的类型,predicate是接收一个int类型的参数,并返回bool变量。
最后
通过刚才的例子讲解,也很容易推断出Where源码和我们预定义的方法差也差不多的!
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
throw new Exception("数据源为空");
foreach (var item in source)
{
if (predicate(item) )
{
yield return item;
}
}
}
最后大家如果喜欢我的文章,还麻烦给个关注, 希望net生态圈越来越好!