当前位置:  开发笔记 > 数据库 > 正文

ToList()?

如何解决《ToList()?》经验,为你挑选了3个好方法。

您是否有在您与LINQ查询结果交易时使用的默认类型?

默认情况下,LINQ将返回一个IEnumerable<>或者一个IOrderedEnumerable<>.我们发现a List<>对我们来说通常更有用,因此ToList()大多数时候习惯于查询我们的查询,并且肯定List<>在我们的函数参数和返回值中使用.

唯一的例外是LINQ to SQL,其中调用.ToList()IEnumerable过早地枚举.

我们也广泛使用WCF,其默认集合类型是System.Array.我们总是System.Collections.Generic.List在VS2008的"服务引用设置"对话框中将其更改为与我们的其余代码库保持一致.

你是做什么?



1> Jon Skeet..:

ToList 总是立即评估序列 - 而不仅仅是在LINQ to SQL中.如果你想要,那很好 - 但并不总是合适的.

就个人而言,我会尽量避免声明您List直接返回- 通常IList更合适,并允许您稍后更改为其他实现.当然,有些操作只是List自己指定的......这种决定总是很棘手.

编辑:(我会把它放在评论中,但它会太笨重.)延迟执行允许您处理太大而不适合内存的数据源.例如,如果您正在处理日志文件 - 将它们从一种格式转换为另一种格式,将它们上传到数据库中,计算出一些统计数据或类似的东西 - 您可以通过流式处理它来处理任意数量的数据,但你真的不要想吸一切到内存中.这可能不是您特定应用的关注点,但需要牢记这一点.


除了表现之外还有很大的差异.特别是,如果有关查询的任何内容(例如源中的数据)发生更改,则延迟执行将为您提供不同的答案.有时这就是你想要的,有时却不是.

2> Timothy Khou..:

我们有相同的场景 - 与服务器的WCF通信,服务器使用LINQtoSQL.

我们在从服务器请求对象时使用.ToArray(),因为客户端更改列表是"非法的".(意思是,没有任何意图支持".Add",".删除"等).

但是,虽然仍在服务器上,但我建议您将其保留为默认设置(不是IEnumerable,而是IQueryable).这样,如果您希望根据某些条件进行更多过滤,则在SQL端进行过滤仍然STILL,直到进行评估.

这是非常重要的一点,因为它意味着令人难以置信的性能增益或损失取决于您的工作.

例:

// This is just an example... imagine this is on the server only. It's the
// basic method that gets the list of clients.
private IEnumerable GetClients()
{
    var result = MyDataContext.Clients;  

    return result.AsEnumerable();
}

// This method here is actually called by the user...
public Client[] GetClientsForLoggedInUser()
{
    var clients = GetClients().Where(client=> client.Owner == currentUser);

    return clients.ToArray();
}

你看到那里发生了什么吗?"GetClients"方法将强制从数据库下载所有"客户端"......然后,在GetClientsForLoogedInUser方法中将发生Where子句以对其进行过滤.

现在,注意一点变化:

private IQueryable GetClients()
{
    var result = MyDataContext.Clients;  

    return result.AsQueryable();
}

现在,直到调用".ToArray"才会进行实际评估......并且SQL将进行过滤.好多了!



3> Daniel Earwi..:

在Linq-to-Objects的情况下,List从函数返回并不像返回那样好IList,正如VENERABLE SKEET指出的那样.但通常你仍然可以做得更好.如果你要返回的东西应该是不可变的,那么IList是一个糟糕的选择,因为它邀请调用者添加或删除东西.

例如,有时你有一个方法或属性返回Linq查询的结果或用于yield return懒惰地生成一个列表,然后你意识到最好在你第一次调用时这样做,将结果缓存到a List然后返回缓存版本.返回时IList可能是一个坏主意,因为调用者可能会出于自己的目的修改列表,这会破坏您的缓存,使其更改对所有其他调用者可见.

最好返回IEnumerable,所以他们只有前向迭代.如果调用者想要快速随机访问,即他们希望他们可以使用[]来通过索引访问,他们可以使用ElementAt,Linq定义它以便它悄悄地嗅探IList并使用它(如果可用的话),如果没有,它会进行哑线性查找.

我曾经使用ToList过的一件事是当我有一个复杂的Linq表达式系统与yield return用于过滤或转换列表的自定义运算符混合在一起时.在调试器中单步执行可能会因为它在执行延迟评估时跳转而变得非常混乱,因此我有时会临时将ToList()添加到几个位置,以便我可以更轻松地遵循执行路径.(虽然如果你正在执行的事情有副作用,这可能会改变程序的含义.)

推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有