哪个IEnumerable To List方式更好?

时间:2012-07-28 12:14:45

标签: c# .net linq collections ienumerable

我想知道以下事实。我有一个数据存储库,它返回IEnumerable<Customer>的所有数据。

在我的业务逻辑中,有时候我需要列表,所以我可以添加一些东西。

当我检索IEnumerable<Customer>时,我有2个选项可以从中获取列表。

使用Linq扩展方法.ToList()或投射它(我认为它不是转换),如(List<Customer>)IEnumerable<Customer>

必须提到我不使用列表进行迭代,所以每次都不需要我的枚举的新副本。在这种情况下,在我的简单情况下,我必须使用强制转换方法而不是.ToList(创建新副本)吗?

// use simple cast?
List<Customer> customers = (List<Customers>)DataSource.GetCustomers(); 

// or if i use this i get a bit of performance loss?
List<Customer> customers = DataSource.GetCustomers().ToList(); 

5 个答案:

答案 0 :(得分:5)

我选择ToList(),因为该方法会返回IEnumerable<Customer>,但您无法确定内部实现。

现在可能GetCustomers()会返回List<>屏蔽的IEnumerable<>,但如果将来内部实施发生变化会怎样?

编辑:

List<Customer>实现了接口IEnumerable<Customer>,以及Customer[]LinkedList<Customer>等数组。因此,当您收到IEnumerable<WhateverClass>类型的对象时,您无法确定它是List<Customer>,当然,仅当您要转换为的类型在界面后面时,该转换才有效,否则你会收到例外。

使用ToList(),正如您所说,您创建了一个包含IEnumerable<>元素的新对象,但至少可以安全地迭代/修改该对象,而不会有任何例外。

这些方法返回IEnumerable<T>,因为这样它就不会绑定到任何特定的集合实现,并且将来它可以在不改变方法签名的情况下从列表切换到数组等等......

答案 1 :(得分:2)

这取决于。如果大小很小,我会使用.ToList(),但你必须明白这将会复制列表。

如果它很大或者你正在做很多事(它会造成性能损失)你可以检查.GetCustomers()返回的对象是否是一个列表 如果是 - 强制转换,则使用.ToList()创建副本。

答案 2 :(得分:1)

我建议使用.ToList()。它会表现得更糟,但是如果你使用了有关API实现细节的信息,那么你就会做出无根据的假设。明天有人会将IEnumerable更改为不是列表的内容,并且您的代码将开始抛出异常。

答案 3 :(得分:1)

您可以通过使用条件来使用强制转换,以防止将来的实施更改。像

这样的东西
List<Customer> customers = null;
try
{
     customers = (List<Customers>)DataSource.GetCustomers();
}
catch
{
    customers = DataSource.GetCustomers().ToList();
}

这样,只要IEnumerable是一个列表,就可以避免复制列表,但是如果由于某种原因,将来内部实现发生变化,你的代码将继续工作。

答案 4 :(得分:0)

您的存储库返回IEnumerable的重点是它不能保证实际上是一个列表。 (可能现在,但IEnumerable的使用允许稍后更改实现。)

使用.ToList()方法,或者让存储库返回List或IList。