IEnumerable vs List - 使用什么?它们是如何工作的? [英] IEnumerable vs List - What to Use? How do they work?

查看:25
本文介绍了IEnumerable vs List - 使用什么?它们是如何工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对枚举器的工作方式和 LINQ 有一些疑问.考虑这两个简单的选择:

I have some doubts over how Enumerators work, and LINQ. Consider these two simple selects:

List<Animal> sel = (from animal in Animals 
                    join race in Species
                    on animal.SpeciesKey equals race.SpeciesKey
                    select animal).Distinct().ToList();

IEnumerable<Animal> sel = (from animal in Animals 
                           join race in Species
                           on animal.SpeciesKey equals race.SpeciesKey
                           select animal).Distinct();

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

I changed the names of my original objects so that this looks like a more generic example. The query itself is not that important. What I want to ask is this:

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

  1. 我注意到,如果我使用 IEnumerable,当我调试和检查sel"(在这种情况下是 IEnumerable)时,它有一些有趣的成员:inner"、outer""、innerKeySelector"和outerKeySelector",最后两个似乎是代表.内部"成员中没有动物"实例,而是物种"实例,这对我来说很奇怪.外部"成员确实包含动物"实例.我想这两个代表决定了哪些进哪些出?

  1. I noticed that if I use IEnumerable, when I debug and inspect "sel", which in that case is the IEnumerable, it has some interesting members: "inner", "outer", "innerKeySelector" and "outerKeySelector", these last 2 appear to be delegates. The "inner" member does not have "Animal" instances in it, but rather "Species" instances, which was very strange for me. The "outer" member does contain "Animal" instances. I presume that the two delegates determine which goes in and what goes out of it?

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

I noticed that if I use "Distinct", the "inner" contains 6 items (this is incorrect as only 2 are Distinct), but the "outer" does contain the correct values. Again, probably the delegated methods determine this but this is a bit more than I know about IEnumerable.

最重要的是,这两个选项中哪一个在性能方面表现最佳?

Most importantly, which of the two options is the best performance-wise?

通过.ToList()的邪恶List转换?

The evil List conversion via .ToList()?

或者直接使用枚举器?

如果可以的话,也请稍微解释一下或提供一些链接来解释 IEnumerable 的这种用法.

If you can, please also explain a bit or throw some links that explain this use of IEnumerable.

推荐答案

IEnumerable 描述行为,而 List 是该行为的实现.当您使用 IEnumerable 时,您可以让编译器有机会将工作推迟到以后,可能会在此过程中进行优化.如果您使用 ToList(),您会强制编译器立即对结果进行具体化.

IEnumerable describes behavior, while List is an implementation of that behavior. When you use IEnumerable, you give the compiler a chance to defer work until later, possibly optimizing along the way. If you use ToList() you force the compiler to reify the results right away.

每当我堆叠"LINQ 表达式时,我都会使用 IEnumerable,因为通过仅指定行为,我让 LINQ 有机会推迟评估并可能优化程序.还记得 LINQ 是如何在您枚举之前不生成查询数据库的 SQL 的吗?考虑一下:

Whenever I'm "stacking" LINQ expressions, I use IEnumerable, because by only specifying the behavior I give LINQ a chance to defer evaluation and possibly optimize the program. Remember how LINQ doesn't generate the SQL to query the database until you enumerate it? Consider this:

public IEnumerable<Animals> AllSpotted()
{
    return from a in Zoo.Animals
           where a.coat.HasSpots == true
           select a;
}

public IEnumerable<Animals> Feline(IEnumerable<Animals> sample)
{
    return from a in sample
           where a.race.Family == "Felidae"
           select a;
}

public IEnumerable<Animals> Canine(IEnumerable<Animals> sample)
{
    return from a in sample
           where a.race.Family == "Canidae"
           select a;
}

现在您有了一个选择初始样本(AllSpotted")以及一些过滤器的方法.所以现在你可以这样做了:

Now you have a method that selects an initial sample ("AllSpotted"), plus some filters. So now you can do this:

var Leopards = Feline(AllSpotted());
var Hyenas = Canine(AllSpotted());

那么使用 List 是否比 IEnumerable 更快?仅当您想防止查询被多次执行时.但总体来说更好吗?好吧,在上面,Leopards 和 Hyenas 被转换为 每个 SQL 查询,并且数据库只返回相关的行.但是如果我们从 AllSpotted() 返回了一个 List,那么它可能会运行得更慢,因为数据库返回的数据可能比实际需要的多得多,而且我们浪费了在客户端进行过滤的周期.

So is it faster to use List over IEnumerable? Only if you want to prevent a query from being executed more than once. But is it better overall? Well in the above, Leopards and Hyenas get converted into single SQL queries each, and the database only returns the rows that are relevant. But if we had returned a List from AllSpotted(), then it may run slower because the database could return far more data than is actually needed, and we waste cycles doing the filtering in the client.

在程序中,将查询转换为列表可能会更好,直到最后,所以如果我要多次列举 Leopards 和 Hyenas,我会这样做:

In a program, it may be better to defer converting your query to a list until the very end, so if I'm going to enumerate through Leopards and Hyenas more than once, I'd do this:

List<Animals> Leopards = Feline(AllSpotted()).ToList();
List<Animals> Hyenas = Canine(AllSpotted()).ToList();

这篇关于IEnumerable vs List - 使用什么?它们是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆