[c#] Cannot apply indexing with [] to an expression of type 'System.Collections.Generic.IEnumerable<>

Is there any specific reason why indexing is not allowed in IEnumerable.

I found a workaround for the problem I had, but just curious to know why it does not allow indexing.

Thanks,

This question is related to c# list generics ienumerable

The answer is


One reason can be that the IEnumerable may contain an unknown number of items. Some implementations produce the list of items as you iterate over it (see yield for samples). That does not work very well with accessing items using an index. which would require you to know that there are at least that many items in the list.


The []-operator is resolved to the access property this[sometype index], with implementation depending upon the Element-Collection.

An Enumerable-Interface declares a blueprint of what a Collection should look like in the first place.

Take this example to demonstrate the usefulness of clean Interface separation:

var ienu = "13;37".Split(';').Select(int.Parse);
//provides an WhereSelectArrayIterator
var inta = "13;37".Split(';').Select(int.Parse).ToArray()[0];
//>13
//inta.GetType(): System.Int32

Also look at the syntax of the []-operator:

  //example
public class SomeCollection{
public SomeCollection(){}

 private bool[] bools;

  public bool this[int index] {
     get {
        if ( index < 0 || index >= bools.Length ){
           //... Out of range index Exception
        }
        return bools[index];
     }
     set {
        bools[index] = value;
     }
  }
//...
}

The IEnumerable<T> interface does not include an indexer, you're probably confusing it with IList<T>

If the object really is an IList<T> (e.g. List<T> or an array T[]), try making the reference to it of type IList<T> too.

Otherwise, you can use myEnumerable.ElementAt(index) which uses the Enumerable.ElementAt extension method. This should work for all IEnumerable<T>s . Note that unless the (run-time) object implements IList<T>, this will cause all of the first index + 1 items to be enumerated, with all but the last being discarded.

EDIT: As an explanation, IEnumerable<T> is simply an interface that represents "that which exposes an enumerator." A concrete implementation may well be some sort of in-memory list that does allow fast-access by index, or it may not. For instance, it could be a collection that cannot efficiently satisfy such a query, such as a linked-list (as mentioned by James Curran). It may even be no sort of in-memory data-structure at all, such as an iterator, where items are generated ('yielded') on demand, or by an enumerator that fetches the items from some remote data-source. Because IEnumerable<T> must support all these cases, indexers are excluded from its definition.


You can use ToList to convert to a list. For example,

SomeItems.ToList()[1]

I had a column that did not allow nulls and I was inserting a null value.


The idea of interfaces is generally to expose a sort of base line contract by which code that performs work on an object can be guaranteed of certain functionality provided by that object. In the case of IEnumerable<T>, that contract happens to be "you can access all of my elements one by one."

The kinds of methods that can be written based on this contract alone are many. See the Enumerable class for tons of examples.

But to zero in on just one concrete one: think about Sum. In order to sum up a bunch of items, what do you need? What contract would you require? The answer is quite simple: just a way to see every item, no more. Random access isn't necessary. Even a total count of all the items is not necessary.

To have added an indexer to the IEnumerable<T> interface would have been detrimental in two ways:

  1. Code that requires the contract described above (access to a sequence of elements), if it required the IEnumerable<T> interface, would be artificially restrictive as it could not deal with any type that did not implement an indexer, even though to deal with such a type should really be well within the capabilities of the code.
  2. Any type that wanted to expose a sequence of elements but was not appropriately equipped to provide random access by index (e.g., LinkedList<T>, Dictionary<TKey, TValue>) would now have to either provide some inefficient means of simulating indexing, or else abandon the IEnumerable<T> interface.

All this being said, considering that the purpose of an interface is to provide a guarantee of the minimum required functionality in a given scenario, I really think that the IList<T> interface is poorly designed. Or rather, the lack of an interface "between" IEnumerable<T> and IList<T> (random access, but no modification) is an unfortunate oversight in the BCL, in my opinion.


you can use indexing if your enumerable type is string like below

((string[])MyEnumerableStringList)[0]

Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to list

Convert List to Pandas Dataframe Column Python find elements in one list that are not in the other Sorting a list with stream.sorted() in Java Python Loop: List Index Out of Range How to combine two lists in R How do I multiply each element in a list by a number? Save a list to a .txt file The most efficient way to remove first N elements in a list? TypeError: list indices must be integers or slices, not str Parse JSON String into List<string>

Examples related to generics

Instantiating a generic type Are these methods thread safe? The given key was not present in the dictionary. Which key? Using Java generics for JPA findAll() query with WHERE clause Using Spring RestTemplate in generic method with generic parameter How to create a generic array? Create a List of primitive int? How to have Java method return generic list of any type? Create a new object from type parameter in generic class What is the "proper" way to cast Hibernate Query.list() to List<Type>?

Examples related to ienumerable

How to concatenate two IEnumerable<T> into a new IEnumerable<T>? Remove an item from an IEnumerable<T> collection Converting from IEnumerable to List Shorter syntax for casting from a List<X> to a List<Y>? filtering a list using LINQ How to check if IEnumerable is null or empty? Convert from List into IEnumerable format IEnumerable vs List - What to Use? How do they work? Cannot apply indexing with [] to an expression of type 'System.Collections.Generic.IEnumerable<> Convert DataTable to IEnumerable<T>