你真的了解C#的Lambda表达式吗?

简介

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;
                }
            }
        }