.net IEnumerable<T> 到 IList 的转换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2000441/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 13:44:08  来源:igfitidea点击:

Conversion of IEnumerable<T> to IList

.netgenericsienumerableilist

提问by John Maloney

If a method takes a parameter of type System.Collections.IList can I legitimately/safely pass a value of type System.Collections.Generic.IEnumerable<T>?

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

I would appreciate a thorough explanation of why this is possible and what actually happens to the object Twhen the IEnumerable<T>is used inside of the method.

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

Is it converted to the base type of Object?

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

Is it used as an System.Collections.IEnumerable?

它用作System.Collections.IEnumerable?

Are there any scenarios where this will cause problems (i.e. performance issues)?

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

Thanks in advance, John

提前致谢,约翰

回答by JaredPar

No, You cannot pass an IEnumerable<T>to a method which takes IList. The interface IEnumerable<T>is not convertible to IListand attempting to pass a variable of type IEnumerable<T>to a method taking IListwill result in a compilation error.

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

In order to make this work you will need to do one of the following

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

  1. Instead of having an IEnumerable<T>, maintain a reference to a type which implements both IEnumerable<T>and IList. List<T>is a good candidate here
  2. Convert the IEnumerable<T>instance to a new object which is convertible to IList. For example, in 3.5+ you can call the .ToList()extension method to create a new List<T>over the enumeration.
  1. 而不是拥有IEnumerable<T>,而是维护对同时实现IEnumerable<T>和的类型的引用IListList<T>是一个很好的候选人
  2. IEnumerable<T>实例转换为可转换为 的新对象IList。例如,在 3.5+ 中,您可以调用.ToList()扩展方法List<T>在枚举上创建新的。

回答by Daniel A. White

回答by Lucas Jones

No. You can't, without using the ToList()extension method. I think that this shouldn't cause thatbig of a performance problem - if you have an alternative, time them and compare.

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

You could also use new List<T>(myIEnumerable)- the documentation says that that function is an O(n)operation, but I can't find anything else about ToList(). Also, remember that List<T>also implements IListas well as IList<T>.

您也可以使用new List<T>(myIEnumerable)- 文档说该函数是一个O(n)操作,但我找不到关于ToList(). 另外请记住,List<T>也农具IList以及IList<T>

回答by David Rutten

IEnumerable does not allow indexed access to the collection, whereas IList does. Thus, IList is more than IEnumerable and you won't be able to get away with it. Of course, some classes implement both interfaces (List<> for example) and those will work fine.

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

If you need to go from IEnumerable to IList, you may try a cast first, if you get lucky it will work. If not, you'll have to foreach over the IEnumerable collection and build a new IList.

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

Edit: use ToList() instead of foreaching yourself as others have suggested.

编辑:使用 ToList() 而不是像其他人建议的那样为自己做准备。

回答by Yuriy Faktorovich

No you can't pass it an IEnumerable. IList implements IEnumerable, so if you pass your method an IList, you can safely use it as an IEnumerable. VS won't compile the following:

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

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

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

Error returned:

错误返回:

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