栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

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

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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 NewWhere(this IEnumerable items,Func predicate)
        {
            List data=new List();
            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 NewWhere(this IEnumerable items,Func predicate)
        {
            List data=new List();
            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 NewWhere(this IEnumerable items,Func predicate)
        {
            //List data=new List();
            foreach(var item in items)
            {
                if(predicate(item))
                {
                    //data.Add(item);
                    yield return item;
                }
            }
            //return data;
        }
    }
}

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

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

课程学习地址

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/910077.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号