14

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

我将不胜感激详细解释为什么这是可能的,以及在方法内部使用T时对象实际发生的情况。IEnumerable<T>

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

它用作System.Collections.IEnumerable?

是否有任何情况会导致问题(即性能问题)?

在此先感谢,约翰

4

5 回答 5

32

,您不能将 an 传递IEnumerable<T>给采用IList. 该接口IEnumerable<T>是不可转换的,IList并且试图将类型变量传递IEnumerable<T>给一个方法IList会导致编译错误。

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

  1. 保持对实现和IEnumerable<T>的类型的引用,而不是。是这里的好人选IEnumerable<T>IListList<T>
  2. IEnumerable<T>实例转换为可转换为的新对象IList。例如,在 3.5+ 中,您可以调用.ToList()扩展方法来创建一个新List<T>的枚举。
于 2010-01-04T16:14:27.500 回答
4

你将不得不打电话ToList()http://msdn.microsoft.com/en-us/library/bb342261.aspx

于 2010-01-04T16:09:41.290 回答
2

不,你不能,不使用ToList()扩展方法。我认为这不应该导致那么大的性能问题 - 如果你有替代方案,请对它们进行计时并进行比较。

您也可以使用new List<T>(myIEnumerable)- 文档说该功能是一项O(n)操作,但我找不到关于ToList(). 另外,请记住,它List<T>也实现IListIList<T>.

于 2010-01-04T16:08:21.043 回答
1

IEnumerable 不允许对集合进行索引访问,而 IList 允许。因此, IList 不仅仅是 IEnumerable ,您将无法摆脱它。当然,有些类同时实现了这两个接口(例如 List<>),它们可以正常工作。

如果您需要从 IEnumerable 转到 IList,您可以先尝试强制转换,如果幸运的话它会起作用。如果没有,您将不得不遍历 IEnumerable 集合并构建一个新的 IList。

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

于 2010-01-04T16:09:58.747 回答
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>'
于 2010-01-04T16:10:00.707 回答