接口返回值使用IEnumerable还是用list,还是IList

搬砖码农SmallNNN 2017-04-06 01:46:42
加精
接口设计中,接口要返回一个集合,返回值使用IEnumerable<T>还是用list<T>,还是||IList<T>?原因是什么?
...全文
6442 60 打赏 收藏 转发到动态 举报
写回复
用AI写文章
60 条回复
切换为时间正序
请发表友善的回复…
发表回复
细嗅蔷薇 2017-04-20
  • 打赏
  • 举报
回复
又学到新姿势了
长空X 2017-04-19
  • 打赏
  • 举报
回复
引用 57 楼 hanjun0612 的回复:
[quote=引用 52 楼 hjkl950217 的回复:]
是不是IQueryable接口 是生成一个查询语句? 这里有点和SQL数据库的语句有点混..
然后就是EF中会大量用到linq 我查看了一下,是IEnumerable类型..如果数据量大的话,会不会比较消耗内存?

你说的很对
http://blog.csdn.net/hanjun0612/article/details/50070081
[/quote]看了这个博文,原来是这样..理解了...,但是我测试了一下(代码如下:),发现生成的SQL语句还是一样的

第二个不用AS运行不了,
上面是IQueryable类型,我推测是不是生成的SQL语句还是调用的IEnumerable接口的生成方法
环境是:VS2015+WIN10+.net4.5+EF6
正怒月神 版主 2017-04-13
  • 打赏
  • 举报
回复
引用 52 楼 hjkl950217 的回复:
是不是IQueryable接口 是生成一个查询语句? 这里有点和SQL数据库的语句有点混.. 然后就是EF中会大量用到linq 我查看了一下,是IEnumerable类型..如果数据量大的话,会不会比较消耗内存?
你说的很对 http://blog.csdn.net/hanjun0612/article/details/50070081
长空X 2017-04-10
  • 打赏
  • 举报
回复
引用 8 楼 hanjun0612 的回复:
[quote=引用 4 楼 u014180504 的回复:] 能举一些实际的应用场景分析下哪个场景哪个最实用的,就是一些最佳实践可以吗,谢谢了
就借着3楼说的。IEnumerable<T>和IQueryable<T> 的区别, IEnumerable<T> 是linq to object。 IQueryable<T> 是linq to sql。 打个比方,我从Users中获取1条数据 var q=db.Users.orderby(x=>x.id).Take(1); 对于IEnumerable<T>来说,他先会把所有数据加载到内存,然后在取一条数据。 对于IQueryable<T> 来说,他会生成一个sql语句,只是取一条数据 [/quote]是不是IQueryable接口 是生成一个查询语句? 这里有点和SQL数据库的语句有点混.. 然后就是EF中会大量用到linq 我查看了一下,是IEnumerable类型..如果数据量大的话,会不会比较消耗内存?
peng2739956 2017-04-10
  • 打赏
  • 举报
回复
说白了,其实这个问题就是一个迭代器的问题。。。。
peng2739956 2017-04-10
  • 打赏
  • 举报
回复
就比如 你需要返回一场串的Long 那这个方法也是

public static IEnumerable<long> AsLongModel()
        {
          
            return new long[] { };
        }
peng2739956 2017-04-10
  • 打赏
  • 举报
回复
在考虑性能的方面上,一般都是返回IEnumerable<T> 这个,我们公司的项目 严令禁止,实体数组不用IEnumerable<T>返回,禁止使用for,只能用LINQ 和Lambda表达式
卧_槽 2017-04-10
  • 打赏
  • 举报
回复
引用 30 楼 closurer 的回复:
我觉得这个问题还可以延伸到函数式编程的一些问题。 可以被 foreach 的迭代器,实际上是一个函数,一个函数返回一个 IEnumerable<T>,实际上是函数套函数。 [quote=引用 27 楼 zanfeng 的回复:] 表示从来不用2.0以上的语法特性。
那不是要返回 object[] 了吗?[/quote] 他们会用ArrayList
  • 打赏
  • 举报
回复
希望大家说出自己的想法的同时也分享自己的设计思路,这样更有利于大家互相学习,
qq_16875871 2017-04-10
  • 打赏
  • 举报
回复
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
  • 打赏
  • 举报
回复
linq 返回值定义为 IEnumerable<T> --> linq to object 返回值定义为 IEnumerable<T> 实际上,linq provider 使用了 IQueryary<T> 这类定义,要比 IEnumerable<T>更具体。因为只有具体的东西,才真正能说明设计接口。linq to object 不具有这些功能,所以它声明到 IEnumerable<T> 这一层。而其它 provider 的原型则希望实现 IQueryary<T>。 相反相成才是设计。不论是在抽象还是具体,两个方面的测试系统、测试用例都能写得非常透彻,都仅仅做必要的事情。不是过分抽象,也不是不做抽象,是恰到好处地刚刚好有一大堆多态应用系统(在这一版本)就是发布的功能中需要这个接口。 抽象的时候,也都是尽可能具体地表达当前的升级、重构需求的。不是为了抽象而抽象。
  • 打赏
  • 举报
回复
软件设计没有什么永远正确的真理给你,唯一的真理就是要与时俱进地重构。在一段阶段内,你写了什么测试用例、搞了什么产品出来,你就定义哪一个级别的抽象接口。 相反相成才是设计,不要走极端。你写出了足以重构产品的测试用例,就让自己真的重构产品了。不要在你还写不出需要什么设计测试的案例时,就做纯理论的、不必要的“设计”。
  • 打赏
  • 举报
回复
linq 返回值定义为 IEnumerable<T>,那是因为它内涵最具体地就只能定义在这一级。而不是因为它要抽像地留有什么空白的中间地带。按照 LINQ 内涵,尽可能地给出最具体的定义,它的内涵只能定义到这一级别。 抽象都是恰到好处地抽象,才叫抽象。如果空洞地弄个什么 string、或者 object 来定义,就叫做万能的抽象了?那就不落地了!
  • 打赏
  • 举报
回复
引用 31 楼 closurer 的回复:
[quote=引用 23 楼 u014180504 的回复:] [quote=引用 19 楼 closurer 的回复:] 从功能上看,没有什么好说的,因为 IEnumerable<T>、List<T>、IList<T> 都是可以互相转换的,无论你返回什么,都不会影响功能上的实现。 不同点是性能上的,假设你在函数里面已经得到了一个 IEnumerable<T>,因为受返回值的限制,执行了 ToList() 方法,这就执行了一次循环,假设这个函数的调用者根本不需要 List<T> 对象,只需要一个迭代器,于是他执行了 List<T> 的迭代器,这就又执行了一次循环……
嗯嗯,确实不能一概而论,肯定是要结合实际的应用场景来具体分析,能把这几个类型的最佳应用场景列举下大概,让我等新手能结合实际学习到更多。谢谢了[/quote] IEnumerable<T> 的应用场景,最典型的就是 System.Linq 的方法了,你可以思考一下为什么 Where<T>(Func<T, bool> predicate) 的返回值是 IEnumerable<T>?[/quote] 哦哦对,linq返回的都是 IEnumerable<T>,然后用的时候再转成想要的类型,是以为 IEnumerable<T>是所有的基类吗,他可以转成任何类型,完成不同的功能
  • 打赏
  • 举报
回复
引用 28 楼 shingoscar 的回复:
能返回List就不要返回IList:如果后面有方法需要IList可以直接传;如果后面需要用到List的属性就能直接用 如果返回的是IList:后面有方法需要List,你得想想我能不能转,或者回去改;如果需要用到List的属性,还得回去改 综上考虑返回范围更广的类型好处多多
就是看调用方要做什么处理来选择用哪个返回类型
  • 打赏
  • 举报
回复
引用 36 楼 closurer 的回复:
如果你留意 .net 的类库,会发现很少有方法返回 List<T> 或 IList<T> 的,但是不知道为什么很多 .net 的程序员喜欢这么做。 可能因为 List<T> 的功能实在太强大了吧。 我认为返回 T[] 或 IEnumerable<T> 会使你的函数的意思更加明确。
确实是这样的
baidu_27549073 2017-04-08
  • 打赏
  • 举报
回复
比如数据层老的技术是返回datatable,反来流行list<modle>这种类型,那我们应该采用哪种通用类型呢?这个可以模仿控件的datasource方法,想一想这两种类型为什么都能绑定到控件呢?
闭包客 2017-04-07
  • 打赏
  • 举报
回复
如果你留意 .net 的类库,会发现很少有方法返回 List<T> 或 IList<T> 的,但是不知道为什么很多 .net 的程序员喜欢这么做。 可能因为 List<T> 的功能实在太强大了吧。 我认为返回 T[] 或 IEnumerable<T> 会使你的函数的意思更加明确。
闭包客 2017-04-07
  • 打赏
  • 举报
回复
引用 25 楼 u014180504 的回复:
[quote=引用 15 楼 hanjun0612 的回复:] [quote=引用 10 楼 u014180504 的回复:] 那在IEnumerable<T>和Ilist<T>两者之间该如何恰当应用?
List<T>,IList<T>都是继承自IEnumerable<T>等等的接口。 其实从这方面,我们就知道List<T>比IList<T>强大,IList<T>比IEnumerable<T>强大。 而返回IEnumerable<T>只是由于调用方可能不一定需要List<T>,也可能是ICollection<T>等等。 所以一个接口存在许多派生情况的时候,使用基类型返回。 而如果只是单一的派生情况,那么久直接返回List<T>,而不是IEnumerable<T>。这里IList<T>的情况也是一样。 说这些,其实也是需要看调用方的具体需求。[/quote] 嗯嗯,因为以前听人说接口返回值范围要尽量小,也不太懂具体意思[/quote] 返回值范围,应该说的不是这个问题。 调用者需要 user_id = 1 的数据,你全部返回了,让调用者去筛选,这是返回值范围的问题。
f1ffffffasd 2017-04-07
  • 打赏
  • 举报
回复
for () { alert "8";}
加载更多回复(31)
C#5.0本质论第四版,高清扫描的,对C#5.0技术讲的比较详细,第1章 C#概述 1 1.1 Hello,World 1 1.2 C#语法基础 3 1.2.1 C#关键字 3 1.2.2 标识符 4 1.2.3 类型定义 5 1.2.4 Main 6 1.2.5 语句和语句分隔符 7 1.2.6 空白 8 1.2.7 使用变量 8 1.2.8 数据类型 9 1.2.9 变量的声明 9 1.2.10 变量的赋值 10 1.2.11 变量的使用 11 1.3 控制台输入和输出 11 1.3.1 从控制台获取输入 11 1.3.2 将输出写入控制台 12 1.3.3 注释 14 1.3.4 托管执行和公共语言基础结构 16 1.3.5 C#和.NET版本 17 1.3.6 CIL和ILDASM 18 1.4 小结 20 第2章 数据类型 21 2.1 基本数值类型 21 2.1.1 整数类型 22 2.1.2 浮点类型 23 2.1.3 decimal类型 23 2.1.4 字面值 24 2.2 更多基本类型 27 2.2.1 布尔类型 27 2.2.2 字符类型 27 2.2.3 字符串 29 2.3 null和void 34 2.3.1 null 34 2.3.2 void 35 2.4 类型的分类 37 2.4.1 值类型 37 2.4.2 引用类型 37 2.5 可空修饰符 38 2.6 数据类型之间的转换 39 2.6.1 显式转型 39 2.6.2 隐式转型 41 2.6.3 不使用转型操作符的类型转换 42 2.7 数组 43 2.7.1 数组的声明 44 2.7.2 数组的实例化和赋值 45 2.7.3 数组的使用 48 2.7.4 字符串作为数组使用 52 2.7.5 常见数组错误 53 2.8 小结 55 第3章 操作符和控制流 57 3.1 操作符 57 3.1.1 一元操作符正和负 58 3.1.2 二元算术操作符 58 3.1.3 复合赋值操作符 64 3.1.4 递增和递减操作符 65 3.1.5 常量表达式和常量符号 68 3.2 控制流程概述 69 3.2.1 if语句 70 3.2.2 嵌套if 71 3.3 代码块 73 3.4 代码块、作用域和声明空间 74 3.5 布尔表达式 76 3.5.1 关系操作符和相等性操作符 77 3.5.2 逻辑布尔操作符 77 3.5.3 逻辑求反操作符 78 3.5.4 条件操作符 79 3.5.5 空接合操作符 80 3.6 按位操作符 80 3.6.1 移位操作符 81 3.6.2 按位操作符 82 3.6.3 按位赋值操作符 83 3.6.4 按位取反操作符 84 3.7 控制流语句(续) 84 3.7.1 while和do while循环 84 3.7.2 for循环 86 3.7.3 foreach循环 88 3.7.4 switch语句 90 3.8 跳转语句 92 3.8.1 break语句 92 3.8.2 continue语句 94 3.8.3 goto语句 95 3.9 C#预处理指令 97 3.9.1 排除和包含代码 98 3.9.2 定义预处理符号 98 3.9.3 生成错误和警告 99 3.9.4 关闭警告消息 99 3.9.5 nowarn:选项 99 3.9.6 指定行号 100 3.9.7 可视编辑器提示 100 3.10 小结 101 第4章 方法和参数 103 4.1 方法的调用 104 4.1.1 命名空间 105 4.1.2 类型名称 106 4.1.3 作用域 107 4.1.4 方法名称 107 4.1.5 形参和实参 107 4.1.6 方法返回值 107 4.1.7 语句与方法调用的比较 108 4.2 方法的声明 108 4.2.1 形式参数声明 109 4.2.2 方法返回类型声明 110 4.3 using指令 111 4.4 Main()的返回值和参数 114 4.5 方法的参数 116 4.5.1 值参数 116 4.5.2 引用参数(ref) 117 4.5.3 输出参数(out) 118 4.5.4 参数数组 120 4.6 递归 122 4.7 方法重载 124 4.8 可选参数 126 4.9 用异常实现基本错误处理 129 4.9.1 捕捉错误 130 4.9.2 使用throw语句报告错误 136 4.10 小结 138 第5章 类 139 5.1 类的定义和实例化 141 5.2 实例字段 144 5.2.1 实例字段的声明 144 5.2.2 实例字段的访问 144 5.3 实例方法 145 5.4 使用this关键字 146 5.5 访问修饰符 151 5.6 属性 153

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧