C# 中IEnumerable与IQuerable的区别

目的

详细理清IEnumerator、IEnumerable、IQuerable三个接口之间的联系与区别

继承关系:IEnumerator->IEnumerable->IQuerable

IEnumerator:枚举器

包含了枚举器含有的方法,谁实现了IEnuemerator接口中的方法,就可以自定义成为一个枚举器。

 public interface IEnumerator{[__DynamicallyInvokable]object Current{[__DynamicallyInvokable]get;}[__DynamicallyInvokable]bool MoveNext();[__DynamicallyInvokable]void Reset();}

实现了IEnumerator接口,就可以获得Current、MoveNext、以及Reset方法,可以实现迭代遍历等操作。
1.Current 返回序列中当前位置项的属性
2.MoveNext 把枚举器位置前进到集合的下一项中
3.Reset 把位置重置为原始状态的方法

public interface IEnumerable{[DispId(-4)][__DynamicallyInvokable]IEnumerator GetEnumerator();}

在这里插入图片描述

IEnumerator就是一个枚举器,包含的方法可以遍历元素。IEnumerable、IQuerable接口中都含有可以获取IEnumerator这个枚举器的GetEnumerator()方法,通过实现GetEnumerator方法来返回对象的枚举器。

IEnumerable接口:获取IEnumerator枚举器

IEnumerable是.NET Framework中的一个基础接口,用于遍历集合中的元素。它提供了一种通用的数据遍历方法,不依赖于数据的具体类型或结构。实现了IEnumerable接口的类或集合可以使用foreach语句进行遍历。枚举器提供了对集合中元素的逐个访问,以此来实现对集合的迭代。 使用 IEnumerable 接口可以使你的集合类通过 foreach 循环来遍历。foreach 循环会自动调用集合的 GetEnumerator() 方法,然后使用枚举器来逐个访问集合中的元素。

实现了IEnumerable接口的类是可枚举类,IEnumerable只有一个成员-GetEnumerator 方法,返回一个对象的枚举器。
在这里插入图片描述

IQuerable接口:同样获取IEnuerator枚举器

IQueryable接口继承自IEnumerable,并为其添加了查询功能。IQueryable主要用于LINQ(Language Integrated Query)查询,它允许开发者使用类似于SQL的语法来查询和操作数据。与IEnumerable不同,IQueryable的查询是可以被优化的,因为它允许查询提供程序在查询执行前分析和优化查询表达式。

IEnumerable与IQuerable接口区别

这两个接口都是用于枚举一系列的元素,但它们的工作方式和应用场景有很大的不同,主要体现在它们如何处理查询和数据访问。

IEnumerable

  • 定义IEnumerable<T>是一个在.NET Framework中用于表示可枚举对象的泛型接口。它定义了一个方法GetEnumerator(),该方法返回一个IEnumerator<T>对象,用于遍历集合中的元素。
  • 使用场景:通常用于内存中的集合,如List、Array等。
  • 扩展方法:LINQ to Objects扩展方法(如SelectWhere等)在IEnumerable<T>上操作,它们接受委托(如Func<T, TResult>)作为参数,直接在内存中的集合上执行操作。
  • 性能:因为这些操作是在内存中直接执行的,所以它们的执行速度通常很快,但可能会受到内存大小和集合大小的限制。

IQueryable

  • 定义IQueryable<T>IEnumerable<T>的扩展,用于支持查询功能。它定义了ExpressionElementType属性,以及ProviderExecute方法。IQueryable<T>通常用于支持查询提供者的集合,如数据库或XML数据源。
  • 使用场景:主要用于数据源查询,如数据库查询,允许延迟执行和查询优化。
  • 扩展方法:虽然IQueryable<T>也支持类似SelectWhere等LINQ扩展方法,但这些方法接受的是Expression<Func<T, TResult>>(或类似的表达式类型)作为参数,而不是简单的Func<T, TResult>。这些表达式被转换成表达式树(Expression Trees),然后可以由查询提供者(如LINQ to SQL或Entity Framework)转换成特定于数据源的查询语言(如SQL)。
  • 性能:因为查询被转换为针对数据源优化的形式(如SQL查询),所以这些查询可能在执行时更加高效,尤其是在处理大量数据时。然而,构建和执行这些查询可能会比直接在内存中处理数据要慢一些。

IEnumerable

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);  
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate); 

IQuerable

public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate);  
public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, int, bool>> predicate);  

在这两个接口的扩展方法中,一个传入的是Func委托,另一个传入的是包装了Func委托的表达式树,表达式树会对查询进行优化,而不是会像前者直接加载到内存中,在进行查询等操作。所以提升了查询效率。

执行时机与性能
IEnumerable:当遍历IEnumerable集合时,数据会被立即加载到内存中,并且查询操作在内存中进行,处理大量数据,可能会消耗大量的内存资源,此外,IEnumerable的查询操作通常不会被优化。
IQuerable:与IEnumerable不同,IQueryable的查询操作是在查询执行时才进行的,而不是在定义查询时。这使得IQueryable能够支持延迟执行(deferred execution)和查询优化。对于大型数据集或远程数据源(如数据库),这种特性可以显著提高性能。

使用场景
IEnumerable
适用于内存中的数据集合,如数组、列表等。当数据量不大,或者需要立即执行查询操作时,使用IEnumerable是合适的。
IQuerable
适用于可以优化的远程数据源,如数据库、Web服务等。当处理大量数据或需要延迟执行查询时,使用IQueryable更为高效。

总结

主要区别在于IQueryable<T>支持将LINQ查询转换为针对数据源优化的查询(如SQL查询),而IEnumerable<T>则在内存中直接操作集合。这种差异导致了在IQueryable<T>的扩展方法中使用Expression<Func<T, TResult>>而不是Func<T, TResult>,因为表达式树可以被查询提供者转换为特定于数据源的查询语言。IEnumerable适用于内存中的数据集合,而IQueryable则更适用于可以优化的远程数据源。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/46893.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣Hot100之两数之和

解法一&#xff1a; 双层循环暴力求解&#xff0c;先在数组的一个位置定住然后在这个位置的后续位置进行判断&#xff0c;如果两个数加起来等于目标和那么就返回 class Solution:def twoSum(self, nums: List[int], target: int) -> List[int]:for i,num in enumerate(num…

Windows 系统利用 SSH 和 WSL2 子系统当服务器

由于最近组内需要将一台 Windows 系统的电脑 W A W_A WA​ 转成能通过 SSH 访问&#xff0c;并且能用 Linux 命令当服务器运行。忙活了一天&#xff0c;终于是把全部东西弄通了。 安装 SSH 首先就是 W A W_A WA​ 先要安装 OpenSSH 服务&#xff0c;直接按照下面的教程安装…

HCIE是什么等级的证书?

HCIE&#xff08;华为认证互联网专家&#xff0c;Huawei Certified Internetwork Expert&#xff09;是华为认证体系中的最高等级证书。它要求考生具备在复杂网络环境中规划、设计、部署、运维和优化网络的能力。HCIE认证是华为认证体系中最具挑战性和含金量的认证之一&#xf…

RocketMQ实现分布式事务

RocketMQ的分布式事务消息功能&#xff0c;在普通消息基础上&#xff0c;支持二阶段的提交。将二阶段提交和本地事务绑定&#xff0c;实现全局提交结果的一致性。 1、生产者将消息发送至RocketMQ服务端。 2、RocketMQ服务端将消息持久化成功之后&#xff0c;向生产者返回Ack确…

NDK R25b 交叉编译FFMpeg4,项目集成,附库下载地址

1.准备工作 文件下载&#xff1a; NDK R25b下载地址&#xff1a;Android NDK历史版本下载网址 - 君*邪 - 博客园 (cnblogs.com) FFmpeg4.4.4 下载地址&#xff1a;https://ffmpeg.org/releases/ffmpeg-4.4.4.tar.xz 环境配置&#xff1a; 本次编译环境是在PC虚拟机中使用U…

普通人还有必要学习 Python 之类的编程语言吗?

在开始前分享一些编程的资料需要的同学评论888即可拿走 是我根据网友给的问题精心整理的对于编程的重要性&#xff0c;这里就不详谈了。 未来&#xff0c;我们和机器的交流会越来越多&#xff0c;编程可以简单看作是和机器对话并分发给机器任务。机器不仅越来越强大&#xff0…

C# —— CRC16 算法

CRC16:即循环冗余校验码。数据通信当中一种常用的查错校验码 其特征信息字段和校验字段的长度可以是任意选定的&#xff0c;对数据进行指定多项式计算 并且将得到的结果附加在帧的后面&#xff0c;接受的设备也执行类似的算法&#xff0c;以保证数据传输的正确性和完整性 crc…

鸿蒙语言基础类库:【@system.configuration (应用配置)】

应用配置 说明&#xff1a; 从API Version 7 开始&#xff0c;该接口不再维护&#xff0c;推荐使用新接口[ohos.i18n]和[ohos.intl]。本模块首批接口从API version 3开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import configurati…

云服务器实际内存与购买不足量问题

君衍 一、本篇缘由二、问题研究1、dmidecode2、dmesg | grep -i memory 三、kdump四、解决方案1、卸载kdump-tools2、清理依赖包3、修改配置文件4、重新生成配置文件5、重启服务器6、再次查看 一、本篇缘由 本篇由于最近买了云服务器&#xff0c;之前基本在本地使用VMware进行虚…

web自动化测试selenium的基本使用

目录 初始化浏览器并打开网页 定位网页元素 定位的方法 模拟键盘操作 模拟鼠标操作 xpath方法 xpath结点 路径表达式 轴 selenium是一个很流行的自动化测试的库&#xff0c;主要用于模拟浏览器的运行&#xff0c;是web应用测试的工具。 在使用selenium时&#xff0c;…

(二)高并发压力测试调优篇——caffeine本地缓存调优

前言 在上一节内容中我们主要介绍了高并发请求下&#xff0c;mysql数据库的调优&#xff0c;其调优的主要原理是尽量减少数据库的IO操作&#xff0c;从而提高服务器的访问性能。在此基础上&#xff0c;本节内容是关于如何利用缓存&#xff0c;提高系统的并发访问能力。我们会首…

Linux部署禅道(无脑复制版)

目录 环境部署1、下载&#xff0c;解压2、启动3、设置开机自启 登录禅道登录数据库1、设置账号2、网页登录数据库 环境 Linux系统 Centos7 《Linux一键安装包安装禅道》视频链接&#xff1a; https://www.zentao.net/zentao-install/zentao-linux-install-80523.html 部署 …

谢启昆:乾隆年间的清廉典范与学术巨擘

谢启昆&#xff0c;一位生活在清朝乾隆年间的杰出人物&#xff0c;以其清廉的政绩和卓越的学术成就&#xff0c;成为后世效仿的典范。他的画像中&#xff0c;目光如炬&#xff0c;透露出坚毅与智慧的光芒&#xff0c;仿佛在诉说着他不平凡的一生。 谢启昆出生在一个书香门第&am…

多元统计分析概述

目录 1. 多元回归分析 2. 主成分分析&#xff08;PCA&#xff09; 3. 因子分析 4. 判别分析 5. 聚类分析 6. 多维尺度分析&#xff08;MDS&#xff09; 结论 多元统计分析是一组用于分析多个变量之间关系的统计方法。它广泛应用于各个领域&#xff0c;如市场研究、生物医…

PHP webshell 免杀方法

本文介绍php类webshell简单的免杀方法&#xff0c;总结不一定全面&#xff0c;仅供读者参考。 webshell通常可分为一句话木马&#xff0c;小马&#xff0c;大马&#xff0c;内存马。 一句话木马是最简单也是最常见的webshell形式&#xff0c;这种木马体积小&#xff0c;隐蔽较…

a newer or same version is present nvidia解决方案

安装时候出现a newer or same version is present nvidia 或者Night Visual Editor 失败&#xff0c;把显卡驱动卸载掉&#xff0c;打开service.mtc 服务控制面板&#xff0c;把nvidia开头的服务全停掉&#xff0c;重新启动cuda安装程序选择自定义安装 vse visual studio相关的…

鸿蒙语言基础类库:【@system.device (设备信息)】

设备信息 说明&#xff1a; 从API Version 6开始&#xff0c;该接口不再维护&#xff0c;推荐使用新接口[ohos.deviceInfo]进行设备信息查询。本模块首批接口从API version 3开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import dev…

手把手教你,如何利用积木易搭3D扫描仪完成文物三维建模?

当前&#xff0c;文物三维建模主要技术手段主要有摄影测量技术、三维激光扫描技术、结构光扫描技术。其中&#xff0c;积木易搭的MagicScan作为一款先进的3D扫描仪&#xff0c;是正是运用了结构光扫描技术的精髓&#xff0c;它巧妙地融合了点云相机的高精度空间数据采集能力、纹…

如何用python写接口

如何用python写接口&#xff1f;具体步骤如下&#xff1a;  1、实例化server 2、装饰器下面的函数变为一个接口 3、启动服务 开发工具和流程&#xff1a; python库&#xff1a;flask 》实例化server&#xff1a;server flask.Flask(__name__) 》server.route(/index,met…