C# LINQ中的Where方法的内部实现

C# LINQ中的Where方法的内部实现

写C#快一年多了,今天在b站搜到一个进阶的课程,打算提高一些自己的水平,然后就开始学习了。课程讲的是我平时开发过程中用的最多的LINQ内部实现和实际运行过程剖析,我会把每节课程的学习内容写成博客记录下来,只为了记录自己的学习和成长过程,如果有人能够从中受益,那我是更加开心啦。

引子:
假设我们有一个0-10的数组,需要挑出所有的奇数,那么我们就可以用Where语句来过滤出满足条件的数字


            var items=new []{1,2,3,4,5,6,7,8,9,10};
            var evenNums=items.Where(x=>x%2==0);
            foreach(var item in evenNums)
            {
                Console.WriteLine(item);
            }

上面的代码可以让我们实现这个需求
但是如果我们在Where的下面一句代码上打一个断点,此时我们发现evenNums里面其实并没有把我们需要的奇数过滤出来,此时的变量evenNums是空的,Where的过滤这步操作其实是到foreach遍历的时才执行的。

下面我们可以自己实现一个Where的功能来看一下效果


using System;
using System.Collections.Generic;
namespace cSharp_Application
{

    public static class IEnumerableExtension
    {
        public static IEnumerable<T> NewWhere<T>(this IEnumerable<T> items,Func<T,bool> predicate)
        {
            List<T> data=new List<T>();
            foreach(var item in items)
            {
                if(predicate(item))
                {
                    data.Add(item);
                }
            }
            return data;
        }
    }
}

用我自己实现的NewWhere去替换LINQ本身的Where以后,可以惊喜的发现,同样的evenNums,现在在执行完下面的一句代码时,已经把需要过滤的条件的过滤出来了,说明LINQ本身的实现方式与我现在的实现是有区别的。从官方文档和比较权威的博客那边的解释是说,LINQ的这种处理方式是一种延迟执行,也就是到了需要取数据时采取执行的

var evenNums=items.NewWhere(x=>x%2==0);
那么如何自己实现这种延迟执行的效果呢???

我们可以把实现NewWhere的代码再仔细看一下

using System;
using System.Collections.Generic;
namespace cSharp_Application
{

    public static class IEnumerableExtension
    {
        public static IEnumerable<T> NewWhere<T>(this IEnumerable<T> items,Func<T,bool> predicate)
        {
            List<T> data=new List<T>();
            foreach(var item in items)
            {
                if(predicate(item))
                {
                    data.Add(item);
                }
            }
            return data;
        }        
    }
}

上面的代码有一个return语句,问题就出在这个return关键字上。
如果我们用下面的方式,配合IEnumerable接口和yield关键字

using System;
using System.Collections.Generic;
namespace cSharp_Application
{

    public static class IEnumerableExtension
    {
        public static IEnumerable<T> NewWhere<T>(this IEnumerable<T> items,Func<T,bool> predicate)
        {
            //List<T> data=new List<T>();
            foreach(var item in items)
            {
                if(predicate(item))
                {
                    //data.Add(item);
                    yield return item;
                }
            }
            //return data;
        }
    }
}

此时,我们自己实现的NewWhere语句也实现了延迟执行的特性

虽然我现在还不知道,微软为什么要设计成这种延迟执行的方式,但是我觉得他这样设计肯定有他自己的理由,说不定就这样子一点点的学习到某个阶段,我就能理解他这么设计的原因了吧。有朝一日我知道了,这么设计的原因时,我会回来更新博客。

课程学习地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值