将IEnumerable <t>转换为IList </t>

时间:2010-01-04 16:07:10

标签: .net generics ienumerable ilist

如果方法采用System.Collections.IList类型的参数,我可以合法/安全地传递类型System.Collections.Generic.IEnumerable<T>的值吗?

我希望在方法内部使用T时,彻底解释为什么这是可能的以及对象IEnumerable<T>实际发生了什么。

它是否转换为Object的基本类型?

是否用作System.Collections.IEnumerable

是否存在导致问题(即性能问题)的情况?

提前致谢, 约翰

5 个答案:

答案 0 :(得分:27)

,您无法将IEnumerable<T>传递给占用IList的方法。接口IEnumerable<T>无法转换为IList,并且尝试将IEnumerable<T>类型的变量传递给采用IList的方法将导致编译错误。

为了完成这项工作,您需要执行以下操作之一

  1. 不要使用IEnumerable<T>,而是维护对同时实现IEnumerable<T>IList的类型的引用。 List<T>是一个很好的候选人
  2. IEnumerable<T>实例转换为可转换为IList的新对象。例如,在3.5+中,您可以调用.ToList()扩展方法在枚举上创建新的List<T>

答案 1 :(得分:4)

答案 2 :(得分:2)

没有。如果不使用ToList()扩展方法,则不能。我认为这不应该导致 大部分性能问题 - 如果你有另一种选择,请计算时间并进行比较。

你也可以使用new List<T>(myIEnumerable) - 文档说该函数是O(n)操作,但我找不到关于ToList()的任何其他内容。另请注意,List<T>还会实现IList以及IList<T>

答案 3 :(得分:1)

IEnumerable不允许对集合进行索引访问,而IList则允许。因此,IList不仅仅是IEnumerable,你将无法逃脱它。当然,有些类实现了两个接口(例如List&lt;&gt;),这些接口都可以正常工作。

如果你需要从IEnumerable转到IList,你可以先尝试演员,如果你运气好,它会起作用。如果没有,你将不得不绕过IEnumerable集合并构建一个新的IList。

编辑:使用ToList()而不是像其他人建议的那样预先自己。

答案 4 :(得分:0)

不,你不能把它传递给IEnumerable。 IList实现了IEnumerable,因此如果您将方法传递给IList,则可以安全地将其用作IEnumerable。 VS不会编译以下内容:

private static void Test(IList<int> list){ }

Test(Enumerable.Range(0, 10));

返回错误:

Argument '1': cannot convert from System.Collections.Generic.IEnumerable<int>' to 'System.Collections.Generic.IList<int>'