java enumerable_IEnumerable vs List-使用什么? 它们如何工作?

我对Enumerators和LINQ的工作方式有疑问。 考虑以下两个简单选择:

List sel = (from animal in Animals

join race in Species

on animal.SpeciesKey equals race.SpeciesKey

select animal).Distinct().ToList();

要么

IEnumerable sel = (from animal in Animals

join race in Species

on animal.SpeciesKey equals race.SpeciesKey

select animal).Distinct();

我更改了原始对象的名称,以使其看起来像一个更通用的示例。 查询本身不是那么重要。 我想问的是:

foreach (Animal animal in sel) { /*do stuff*/ }

我注意到,如果我使用IEnumerable ,则在调试和检查“ sel”(在这种情况下就是IEnumerable)时,它具有一些有趣的成员:“ inner”,“ outer”,“ innerKeySelector”和“ outerKeySelector”,这最后两个似乎是代表。 “内部”成员中没有“动物”实例,而是“物种”实例,这对我来说很奇怪。 “外部”成员确实包含“动物”实例。 我假设这两个代表确定哪个进出什么?

我注意到,如果我使用“ Distinct”,则“ inner”包含6个项目(这是不正确的,因为只有2个是Distinct),但是“ outer”确实包含正确的值。 同样,可能委托方法确定了这一点,但这比我对IEnumerable的了解还多。

最重要的是,这两个选项中哪个是性能最佳的?

通过.ToList()邪恶列表转换?

还是直接使用枚举器?

如果可以的话,也请解释一下或抛出一些链接来解释IEnumerable的用法。

#1楼

没有人提到一个关键的差异,具有讽刺意味的是,作为一个重复的问题,有人回答了一个封闭的问题。

IEnumerable是只读的,而List不是。

#2楼

有一篇非常不错的文章由:Claudio Bernasconi的TechBlog撰写: 何时使用IEnumerable,ICollection,IList和List

这里是有关方案和功能的一些基本知识:

4dKYm.png

ab5d21dfbef5f88ec40350f283e263a6.png

#3楼

要实现的最重要的事情是,使用Linq,查询不会立即得到评估。 它仅作为在foreach中迭代生成的IEnumerable一部分而运行-这就是所有奇怪的委托正在做的事情。

因此,第一个示例通过调用ToList并将查询结果放入列表中来立即评估查询。

第二个示例返回一个IEnumerable ,其中包含稍后运行查询所需的所有信息。

就性能而言,答案取决于它 。 如果您需要一次评估结果(例如,您要对稍后查询的结构进行变异,或者您不希望IEnumerable上的迭代花费很长时间),请使用列表。 否则使用IEnumerable 。 默认情况下,应该在第二个示例中使用按需评估,因为通常会使用较少的内存,除非有特殊原因将结果存储在列表中。

#4楼

如果您只想枚举它们,请使用IEnumerable 。

但是请注意,更改要枚举的原始集合是一项危险的操作-在这种情况下,您将需要首先ToList 。 这将为内存中的每个元素创建一个新的list元素,枚举IEnumerable ,因此如果仅枚举一次,则性能会降低-但更安全,有时List方法很方便(例如,在随机访问中)。

#5楼

IEnumerable的优点是延迟执行(通常使用数据库)。 在您实际遍历数据之前,查询将不会执行。 这是一个查询,直到需要它为止(又称延迟加载)。

如果您调用ToList,查询将被执行,或者像我想说的那样“物化”。

两者都有优点和缺点。 如果调用ToList,则可以消除执行查询时的神秘性。 如果坚持使用IEnumerable,您将获得以下优势:该程序在实际需要之前不会执行任何工作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值