首页 > C# > IEnumerable 和 List 用法区别是什么?

IEnumerable 和 List 用法区别是什么?

上一篇 下一篇

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

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();

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

foreach (Animal animal in sel) { /*do stuff*/ }
  1. 我注意到,如果我使用 ,当我调试和检查“sel”时,在这种情况下是 IEnumerable,它有一些有趣的成员:“inner”、“outer”、“innerKeySelector”和“outerKeySelector”,最后 2 个似乎是委托。“内部”成员中没有“动物”实例,而是“物种”实例,这对我来说很奇怪。“外部”成员确实包含“动物”实例。我想两位代表决定哪些进入,哪些退出?IEnumerable
  2. 我注意到,如果我使用“独特”,则“内部”包含 6 个项目(这是不正确的,因为只有 2 个是 Distinct),但“外部”确实包含正确的值。同样,可能是委托的方法确定了这一点,但这比我对IEnumerable的了解要多一点。
  3. 最重要的是,这两个选项中哪一个在性能方面是最好的?

邪恶名单转换通过 ?.ToList()

或者直接使用枚举器?

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

网友回答:

IEnumerable描述行为,而 List 是该行为的实现。使用 时,您给编译器一个将工作推迟到以后的机会,可能会在此过程中进行优化。如果使用 ToList(),则强制编译器立即调整结果。IEnumerable

每当我“堆叠”LINQ 表达式时,我都会使用 ,因为通过仅指定行为,我让 LINQ 有机会延迟计算并可能优化程序。还记得 LINQ 在您枚举数据库之前不会生成 SQL 来查询数据库吗?考虑一下:IEnumerable

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”)以及一些筛选器的方法。所以现在你可以这样做:

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

那么使用列表是否更快?仅当您要防止多次执行查询时。但总体上更好吗?在上面,豹和鬣狗分别被转换为单个SQL查询,数据库只返回相关的行。但是,如果我们从 返回了一个 List,那么它的运行速度可能会变慢,因为数据库返回的数据可能远远超过实际需要的数据,并且我们浪费了在客户端中进行过滤的周期。IEnumerableAllSpotted()

在程序中,最好将查询转换为列表推迟到最后,因此,如果我要多次枚举豹子和鬣狗,我会这样做:

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

分割线

网友回答:

有一篇非常好的文章:Claudio Bernasconi的TechBlog:何时使用IEnumerable,ICollection,IList和List

分割线

网友回答:

实现的类允许您使用该语法。IEnumerableforeach

基本上,它有一个获取集合中下一项的方法。它不需要整个集合都在内存中,也不知道其中有多少项,只是不断获取下一个项,直到用完为止。foreach

这在某些情况下非常有用,例如,在大型数据库表中,您不希望在开始处理行之前将整个内容复制到内存中。

现在实现 ,但表示内存中的整个集合。如果你有一个 并且你调用,则创建一个新列表,其中包含内存中的枚举内容。ListIEnumerableIEnumerable.ToList()

linq 表达式返回枚举,默认情况下,当您使用 .linq 语句在迭代 时执行,但您可以使用 强制它更快地迭代。foreachIEnumerableforeach.ToList()

我的意思是:

var things = 
    from item in BigDatabaseCall()
    where ....
    select item;

// this will iterate through the entire linq statement:
int count = things.Count();

// this will stop after iterating the first one, but will execute the linq again
bool hasAnyRecs = things.Any();

// this will execute the linq statement *again*
foreach( var thing in things ) ...

// this will copy the results to a list in memory
var list = things.ToList()

// this won't iterate through again, the list knows how many items are in it
int count2 = list.Count();

// this won't execute the linq statement - we have it copied to the list
foreach( var thing in list ) ...

模板简介:该模板名称为【IEnumerable 和 List 用法区别是什么?】,大小是暂无信息,文档格式为.编程语言,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【C#】栏目查找您需要的精美模板。

相关搜索
  • 下载密码 lanrenmb
  • 下载次数 441次
  • 使用软件 Sublime/Dreamweaver/HBuilder
  • 文件格式 编程语言
  • 文件大小 暂无信息
  • 上传时间 03-07
  • 作者 网友投稿
  • 肖像权 人物画像及字体仅供参考
栏目分类 更多 >
热门推荐 更多 >
单页式简历模板 企业网站 响应式 自适应 微信模板 微信公众平台 微信素材 微信文章 html5 微信图片
您可能会喜欢的其他模板