Sorry for such a vague question, but I have been searching around for the best part of a day, I have read article after article (and many questions here) but just cannot find an easy to understand answer.
I (think I) know what IEnumerable is for, but I just can't understand what it means when it is defined with a generic type argument, for example:
IEnumerable<int> test = method();
This is just driving me mad! Please put me out of misery and explain what it means?
An
IEnumerable
is basically a collection of objects. It has the methodGetEnumerator()
which allows you to iterate through all of the objects in the enumerable.An
IEnumerable<int>
is basically a collection of integers. It has the methodGetEnumerator()
which allows you to iterate through all of the integers in the enumerable.IEnumerable<int> test = method();
means thatmethod()
is getting a collection if integers from somewhere. It could be a List, an array or some other data type, but it is definitely a group of them and they are all integers, and you have the ability to iterate through them.This post may be helpful as well: What's the difference between IEnumerable and Array, IList and List?
The word you're looking for is "generics", and the example you give is IEnumerable being used as a generic for items of type int. What that means is that the IEnumerable collection you are using is strongly-typed to only hold int objects as opposed to any other type.
Google "C# generics IEnumerable" and you will find all of the information you want on this.
An
IEnumerable
has aGetEnumerator
method which will return anIEnumerator
, whoseCurrent
method will return anObject
. AnIEnumerable<T>
has aGetEnumerator
method which will return anIEnumerator<T>
, whoseCurrent
method will return aT
. If you know in advance the expected type of the object to be returned by the enumerator, it's generally better to use the generic form.Another distinction is that
IEnumerator<T>
inheritsIDisposable
, which allows code which is done with an enumerator to callDispose
on it without having to worry about whether it is supported. By comparison, when using a non-genericIEnumerator
, it's necessary to test whether it isIDisposable
and callDispose
on it if so. Note that use of the non-generic form ofIEnumerable
/IEnumerator
does not relieve one of the requirement to callDispose
. As an example, casting the vb-style Collection toIEnumerable
and then callingGetEnumerator
100,000 times without callingDispose
will be extremely slow (many seconds, even on an i7) unless a garbage-collection happens to occur. Disposing theIEnumerator
after each call will speed things up more than a hundredfold.IEnumerable means it can be used in a foreach loop.
test
can be used in the form ofI just think of
IEnumerable<int>
the same way as I'd think of aList<int>
, which comes a little bit more naturally I suppose. With the caveat that anIEnumerable<int>
doesn't do quite as much as aList<int>
, and that essentially it's just a thing of ints that can be enumerated