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.mfbz.cn/a/803407.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

R语言模型评估网格搜索

### 网格搜索 ### install.packages("gbm") set.seed(1234) library(caret) library(gbm) fitControl <- trainControl(method repeatedcv,number 10,repeats 5) # 设置网格搜索的参数池 gbmGrid <- expand.grid(interaction.depth c(3,5,9),n.trees (1:2…

走进NoSql

一、引入 1.1什么是NoSql NoSQL&#xff08;Not Only SQL&#xff09;是一组非关系型数据库&#xff08;或称为非SQL数据库&#xff09;的统称&#xff0c;它们提供了与传统的关系型数据库不同的数据存储和检索方式。NoSQL数据库通常用于处理大量的、分布式的、非结构化或半结…

Lora模型训练的参数-学习笔记

任何一个lora都会有三重属性&#xff0c;易调用性、泛化性和还原性&#xff0c;任何一个lora只能完美满足其中的两项&#xff1b; 易调用性&#xff1a;在已调用lora后&#xff0c;还需要多少提示词才能让该lora完全生效&#xff1b; 泛化性&#xff1a;能不能还原lora训练素…

全网超详细Redis主从部署(附出现bug原因)

主从部署 整体架构图 需要再建两个CentOs7,过程重复单机部署 http://t.csdnimg.cn/zkpBE http://t.csdnimg.cn/lUU5gLinux环境下配置redis 查看自己ip地址命令 ifconfig 192.168.187.137 进入redis所在目录 cd /opt/software/redis cd redis-stable 进入配置文件 vim redi…

git查看历史记录方法

0 Preface/Foreword 1 git reflog git reflog显示所有的操作&#xff0c;不仅仅是commit&#xff0c;也包括git pull&#xff0c;checout等动作。 1.1 查看本地和远程仓库的区别 远程仓库&#xff1a;中间的提交是直接在web端编辑 远程仓库&#xff1a;最新的提交是在本地编…

原码、补码、反码、移码是什么?

计算机很多术语翻译成中文之后&#xff0c;不知道是译者出于什么目的&#xff0c;往往将其翻译成一个很难懂的名词。 奇怪的数学定义 下面是关于原码的“吐槽”&#xff0c;可以当作扩展。你可以不看&#xff0c;直接去下一章&#xff0c;没有任何影响。 原码的吐槽放在前面是…

Java修仙之路,十万字吐血整理全网最完整Java学习笔记(进阶篇)

导航&#xff1a; 【Java笔记踩坑汇总】Java基础JavaWebSSMSpringBootSpringCloud瑞吉外卖/黑马旅游/谷粒商城/学成在线设计模式面试题汇总性能调优/架构设计源码-CSDN博客 推荐视频&#xff1a; 黑马程序员全套Java教程_哔哩哔哩 尚硅谷Java入门视频教程_哔哩哔哩 推荐书籍&am…

基础动态规划题目基础动态规划题目

目录 题目1&#xff1a; P1216 [USACO1.5] [IOI1994]数字三角形 Number Triangles 代码示例&#xff1a; 题目2&#xff1a; Common Subsequence 代码示例 题目3 &#xff1a;最长上升子序列 最长不下降子序列 最长上升子序列oj答案 题目1&#xff1a; P1216 [USACO1.5]…

ASP.NET Core中创建中间件的几种方式

前言 今天我们一起来盘点一下在ASP.NET Core应用程序中添加和创建中间件常见的四种方式。 中间件介绍 ASP.NET Core中间件&#xff08;Middleware&#xff09;是用于处理HTTP请求和响应的组件&#xff0c;它们被安排在请求处理管道中&#xff0c;并按顺序执行。中间件的设计是为…

15- 微分方程

对三角函数不敏感

快捷:通过胶水语言实现工作中测试流程并行、加速

通过胶水语言实现工作中测试流程并行、加速 通过胶水语言实现工作中测试流程并行、加速工作场景&#xff08;背景&#xff09;问题抽象&#xff08;挑战&#xff09;如何做&#xff08;行动&#xff09;获得了什么&#xff08;结果&#xff09;后记相关资源 通过胶水语言实现工…

十大排序 之 快速排序

&#xff01;&#xff01;&#xff01;排序仅针对于数组哦本次排序是按照升序来的哦代码后边有图解哦 介绍 快速排序英文名为Quick Sort 基本思路 快速排序采用的是分治思想&#xff0c;即在一个无序的序列中选取一个任意的基准元素base&#xff0c;利用base将待排序的序列分…

【BUG】已解决:error: subprocess-exited-with-error

已解决&#xff1a;error: subprocess-exited-with-error 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c;武汉城市开发者社区主…

Ubuntu上安装配置samba服务

Ubuntu上安装配置samba服务 在Ubuntu中安装配置samba共享服务&#xff0c;可以让你在网络上共享文件和打印机。以下是一个相对详细的步骤指南&#xff0c;介绍如何在Ubuntu上安装和配置Samba。 1. 安装Samba 首先&#xff0c;需要安装Samba软件包。打开终端并运行以下命令&a…

Python基础语法篇(上)

Python基础语法&#xff08;上&#xff09; 一、基知二、基本数据类型&#xff08;一&#xff09;标准数据类型&#xff08;二&#xff09;数据类型转换 三、字符串基本操作&#xff08;一&#xff09;字符串的索引和切片&#xff08;二&#xff09;字符串的拼接 三、运算符四、…

新一代大语言模型 GPT-5 对工作与生活的影响及应对策略

文章目录 &#x1f4d2;一、引言 &#x1f4d2;二、GPT-5 的发展背景 &#x1f680;&#xff08;一&#xff09;GPT-4 的表现与特点 &#x1f680;&#xff08;二&#xff09;GPT-5 的预期进步 &#x1f4d2;三、GPT-5 对工作的影响 &#x1f680;&#xff08;一&#xf…

STM32使用Wifi连接阿里云

目录 1 实现功能 2 器件 3 AT指令 4 阿里云配置 4.1 打开阿里云 4.2 创建产品 4.3 添加设备 5 STM32配置 5.1 基础参数 5.2 功能定义 6 STM32代码 本文主要是记述一下&#xff0c;如何使用阿里云物联网平台&#xff0c;创建一个简单的远程控制小灯示例。 完整工程&a…

元宇宙深入解析

元宇宙&#xff08;Metaverse&#xff09;是一个新兴的概念&#xff0c;它激发了技术专家、艺术家和商业领袖的无限想象。它代表着数字互动的新前沿&#xff0c;提供了一个平行的数字宇宙&#xff0c;用户可以在其中实时互动&#xff0c;超越物理世界的限制。 元宇宙是什么&am…

【java】力扣 合法分割的最小下标

文章目录 题目链接题目描述思路代码 题目链接 2780.合法分割的最小下标 题目描述 思路 这道题是摩尔算法的一种扩展 我们先可以找到候选人出来&#xff0c;然后去计算他在左右两边元素出现的次数&#xff0c;只有当他左边时&#xff0c;左边出现的次数2 >左边的长度&…

【C++】拷贝构造函数及析构函数

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文由 JohnKi 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f4e2;未来很长&#…