开发者

Conversion of IEnumerable<T> to IList

If a method takes a parameter of type System.Collections.IList can I legitimately/safely pass a v开发者_C百科alue of type System.Collections.Generic.IEnumerable<T>?

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

Is it converted to the base type of Object?

Is it used as an System.Collections.IEnumerable?

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

Thanks in advance, John


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

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.


You will have to call ToList(). http://msdn.microsoft.com/en-us/library/bb342261.aspx


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

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 IList as well as IList<T>.


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.

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.

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


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:

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>'


Following code was an attempt of mine to convert from IEnumerable<IEnumerable> to IList<IList>.

IEnumerable<IEnumerable<int>> iEnumerableOfIEnumerable = new List<IEnumerable<int>>();
IList<IList<int>> iListOfIList = new List<IList<int>>(
    iEnumerableOfIEnumerable.Select(list => list.ToList()));
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜