首页 程序笔记 Linq to Object的Where和Select实现原理

Linq to Object的Where和Select实现原理

Linq的Where是一个基于委托的代码封装,把数据筛选的通用逻辑完成,把判断逻辑交给委托传递。Select是基于委托的代码封装,把数据转换的通用逻辑完成,把转换逻辑交给委托传递。

Linq还有很多方法,这些方法大多都是基于委托的代码封装,也有一些是不需要委托的,例如Sum。

实现方法是把通用逻辑写好,把可变逻辑当成委托传递。

namespace MyStudy
{
    public static class LinqExtension
    {
        /// <summary>
        /// 与官方Where一样,迭代器返回Ienumerable,按需获取
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tList"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static IEnumerable<T> MyWhere<T>(this IEnumerable<T> tList, Func<T, bool> func) {
            foreach (var t in tList) {
                if (func.Invoke(t)) {
                    yield return t;
                }
            }
        }
        /// <summary>
        /// 也能实现Where功能,一次性返回结果集
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tList"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static List<T> MyWhereList<T>(this List<T> tList, Func<T, bool> func) {
            List<T> result = new List<T>();
            foreach (var t in tList) {
                if (func.Invoke(t)) {
                    result.Add(t);
                }
            }
            return result;
        }
        public static IEnumerable<T1> MySelect<T, T1>(this IEnumerable<T> tList, Func<T, T1> func) {
            foreach (var t in tList) {
                yield return func.Invoke(t);
            }
        }
    }
}

代码中yield return是语法糖,返回Ienumerable结果集时,编译器会生成很多代码,是一个迭代器,能够实现数据按需加载。

Console测试运行代码

namespace MyStudy
{
    class Program
    {
        static void Main(string[] args)
        {
            var testEntities = new List<TestEntity>() {
                new TestEntity(){
                    Id = 1,
                    Name="Name1",
                    Age=18
                },
                new TestEntity(){
                    Id = 2,
                    Name="Name2",
                    Age=11
                },
                new TestEntity(){
                    Id = 3,
                    Name="Name3",
                    Age=19
                }
            };
            var list1 = testEntities.MyWhere(x => x.Id > 1);
            foreach (var item in list1) {
                Console.WriteLine(item.Name);
            }
            var list2 = testEntities.Where(x => x.Id > 1);
            foreach (var item in list1)
            {
                Console.WriteLine(item.Name);
            }
            var list3 = testEntities.MySelect(x => new { Id = x.Id, Name = x.Name });
            foreach (var item in list3)
            {
                Console.WriteLine(item.Name);
            }
            var list4 = testEntities.Select(x => new { Id = x.Id, Name = x.Name });
            foreach (var item in list4)
            {
                Console.WriteLine(item.Name);
            }
            //分解写法
            Func<TestEntity, bool> func = new Func<TestEntity, bool>(t => t.Id > 1);
            var list5 = testEntities.Where(func);
            foreach (var item in list5)
            {
                Console.WriteLine(item.Name);
            }
            Console.ReadLine();
        }
    }
}

Linq to Object和Linq to Sql的区别:

Linq to Object 数据源是内存里的集合,传递的是委托。

Linq to Sql 数据源来自数据库,传递的是lanmbda表达式目录树(Expression<Func<TSource,bool>>),解析表达式转化成Sql语句。

2

站心网

Linq的Where是一个基于委托的代码封装,把数据筛选的通用逻辑完成,把判断逻辑交给委托传递。Select是基于..

为您推荐

ZLinq:.NET 高性能 LINQ 替代方案及其使用指南

在 .NET 开发中,LINQ(Language Integrated Query)为数据查询提供了简洁且强大的语法。然而,传统的 LINQ 在处理大量数据时可能会引发性能瓶颈,主要由于频繁的内存分配和对象创建。为解决这一问题,Cysharp 团队..

为什么说 LINQ 要胜过 SQL

如果你还没有沉溺于 LINQ,就会想这有啥大惊小怪的。SQL 并没有坏掉,为什么还要对它进行修补呢? 为什么我们还需要另外一种查询语言呢?流行的说法是 LINQ 同C#(或者 VB)集成在了一起,故而消除了编程语言和数据库..

使用 html2canvas 实现截图功能

html2canvas 是一个开源的 JavaScript 库,用于将网页上的 HTML 元素渲染成图像。它通过遍历页面的 DOM 树和计算样式,然后将其绘制到 <canvas> 元素上,最终生成图片。该库不依赖服务器端,而是通过浏览器端的 Java..

网站统计中的访问信息收集的前端实现

网站数据统计分析工具是网站站长和运营人员经常使用的一种工具,比较常用的有谷歌分析、百度统计和腾讯分析等等。所有这些统计分析工具的第一步都是网站访问数据的收集。目前主流的数据收集方式基本都是基于javascri..

使用SuperWebSocket实现Web消息推送

在大部分Web系统中,我们可能遇到需要向客户端推送消息的需求。SuperWebSocket第三方库能让我们轻松的完成任务。SuperWebSocket第三方库可以从网上下载,不过通过Visual Studio Nuget安装更快。引用SuperWebSocket相..

.NET C# 使用Hook钩子实现全局监听键盘和鼠标

C# 是一种面向对象的编程语言,具有丰富的类库和工具支持,适用于各种类型的应用程序开发。Windows 提供了一种称为"钩子"(Hook)的机制,允许拦截并处理系统级别的事件,如键盘按键和鼠标移动。通过结合 C# 和 Hook..

.NET C#连接FTP实现文件上传下载

在 .NET 中可以使用 System.Net.FtpWebRequest 类来连接 FTP 服务器,实现文件上传和下载。以下是实现文件上传和下载的完整代码示例。1. 上传文件到 FTP 服务器using System;using System.IO;using System.Net;class..

C#使用 Attribute 实现 AOP 功能

在 C# 中,通过自定义 Attribute 并结合一些技术(如动态代理、反射等)可以实现 AOP(面向切面编程)。AOP 通常用于日志记录、性能监控、权限验证等横切关注点。以下是一个使用 C# Attribute 实现 AOP 功能的示例。..

使用CSS columns-visibility实现砌体布局

CSS的 columns 属性(如 columns、column-count 和 column-width)通常用于多列文本布局,而不是直接用于砌体布局。然而,结合 columns 和 visibility 属性,可以在某些情况下实现类似砌体布局的效果,虽然它并不完..

使用System.Linq.Dynamic.Core扩展库动态构建 LINQ 查询

System.Linq.Dynamic.Core 是一个扩展库,用于在运行时动态构建 LINQ 查询,支持字符串形式的表达式解析和动态查询操作。它是 .NET 的一个强大工具,适合处理需要灵活定义查询逻辑的场景,例如动态过滤、排序、投影..

js使用IntersectionObserver实现锚点在当前页面视口时导读高亮

在 JavaScript 中可以通过监听页面滚动事件,检查每个锚点的位置,并根据当前滚动位置高亮相应的导航项,从而实现页面内锚点链接的导读高亮效果。交叉观察器 API(Intersection Observer API)提供了一种异步检测目..

js使用scroll事件实现锚点滚动到页面顶部时导航高亮

在 JavaScript 中,可以通过监听页面滚动事件,并判断页面顶部与各个锚点的距离来实现导航高亮效果。当某个锚点的内容块滚动到页面顶部时,自动高亮相应的导航项。以下是实现方式:1. HTML 结构假设我们有多个内容区..

Blazor的N种渲染模式原理和常见问题说明

我们从下面这幅图开始,下图显示了三种渲染模式,分别称之为静态SSR、交互式SSR(即之前的BlazorServer)、交互式CSR(即之前的BlazorWasm)。还有一种渲染模式BlazorHybrid,稍后说。一、先浅层理解一个图例静态SSR:经..

ASP.NET Core实现多语言本地化Web应用程序

构建全球可访问的网站和应用程序需要对内容进行适当的本地化,以吸引来自不同文化和地区的用户。ASP.NET Core 提供强大的本地化支持,以用户首选的语言和格式呈现内容。在本综合指南中,我们将探索 ASP.NET Core 中..

支付宝第三方支付平台对接原理和实现

如果把商户网站使用第三方支付平台(比如支付宝)的原理搞清楚,那编程就变得简单多了。 整个过程大致这样: 1、商户与支付宝签约。 2、在商户网站购买商品,填写数量,确定购买后跳转到结账页面。结账页面可能包括订..

类似php iconv的函数功能,C#实现方法

在与一个第三方接口对接时,发现对方无法用GZip解压我发过去的数据,看了对方PHP的示例代码,发现对方使用的是PHP的$file = iconv("IOS-8859-1","UTF-8",gzencode($data_json));大致意思是要先压缩,在把压缩的数组..

c#实现与Java无差异的GZip压缩和GZip解压缩

c#实现与Java无差异的GZip压缩和GZip解压缩,其中有个坑就是GZip压缩的时候,只有在GZipStream在Dispose后调应对应MemoryStream.ToArray()所得到的结果才是正确的压缩数据。如果在zipStream.Write(bytes, 0, bytes.L..

.NET Core 管道模型中间件及管道模拟实现

管道,PipelineASP.NET Core 路由,认证,绘画,缓存,都是由管道来处理的中间件。MVC WEB API,都是建立在某个特殊的中间件之上。MVC,路由的中间件,请求地址和控制器之间的映射,在此基础上实现了实例化控制器,..

.Net各版本多线程使用原理和实践

多线程基本概念进程:程序在服务器上运行时,占据的计算资源合集,称之为进程。进程之间不会互相干扰,进程间的通信比较困难(分布式)。线程:程序执行的最小单位。线程也包含自己的计算资源,线程是属于进程的,一..

ASP.NET MVC4/5实现asp-append-version为css/js带上版本号

.NET Core MVC/Razor Page中使用TagHelpers的asp-append-version属性就可以为css或者js文件加上版本号。例如:<linkrel="stylesheet"href="~/css/site.min.css"asp-append-version="true"/>这样输出的Html是这样的:..

发表回复

返回顶部