如果方法采用System.Collections.IList类型的参数,我可以合法/安全地传递类型System.Collections.Generic.IEnumerable<T>
的值吗?
我希望在方法内部使用T
时,彻底解释为什么这是可能的以及对象IEnumerable<T>
实际发生了什么。
它是否转换为Object的基本类型?
是否用作System.Collections.IEnumerable
?
是否存在导致问题(即性能问题)的情况?
提前致谢, 约翰
答案 0 :(得分:27)
否,您无法将IEnumerable<T>
传递给占用IList
的方法。接口IEnumerable<T>
无法转换为IList
,并且尝试将IEnumerable<T>
类型的变量传递给采用IList
的方法将导致编译错误。
为了完成这项工作,您需要执行以下操作之一
IEnumerable<T>
,而是维护对同时实现IEnumerable<T>
和IList
的类型的引用。 List<T>
是一个很好的候选人IEnumerable<T>
实例转换为可转换为IList
的新对象。例如,在3.5+中,您可以调用.ToList()
扩展方法在枚举上创建新的List<T>
。 答案 1 :(得分:4)
您必须致电ToList()
。
http://msdn.microsoft.com/en-us/library/bb342261.aspx
答案 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>'