What is the difference between IEnumerable
and IEnumerable<T>
?
I've seen many framework classes implementing both these interfaces, therefore I would like to know what advantages one get by implementing both?
Please have a look how they've been defined:
public interface IEnumerable { [DispId(-4)] IEnumerator GetEnumerator(); } public interface IEnumerable<T> : IEnumerable { IEnumerator<T> GetEnumerator(); }
As we see, IEnumerable<T>
derives from IEnumerable
, that means whatever IEnumerable
has, IEnumerable<T>
inherits, then why do we implement both instead of just IEnumerable<T>
? Is implementing IEnumerable<T>
not enough?
Likewise, there are other similar pairs:
IList
and IList<T>
ICollection
and ICollection<T>
I would like to know about these as well.
IEnumerable<T> is the base interface for collections in the System. Collections. Generic namespace such as List<T>, Dictionary<TKey,TValue>, and Stack<T> and other generic collections such as ObservableCollection<T> and ConcurrentStack<T>.
IEnumerable vs List. The main difference between IEnumerable and List in C# is that IEnumerable is an interface, while List is a concrete class. Moreover, IEnumerable is read-only and List is not.
Enumerable- It is a class and Provides a set of static methods for querying objects that implement IEnumerable. IEnumerable is an interface. Enumerable is helper class which implements the method of IEnumerable interface. IEnumerable is just pure abstract class.
The IEnumerable interface declares only one method called GetEnumerator which returns another type of interface called the IEnumerator interface for that particular collection. IEnumerator, on the other hand, is the base interface for all non-generic enumerators which are used to read the data in the collection.
Basically the nongeneric interfaces came first, in .NET 1.0 and 1.1. Then when .NET 2.0 came out, the generic equivalents came out. Life would have been a lot simpler if generics had made it into .NET 1.0 :)
In terms of implementing "only" IEnumerable<T>
instead of both - you basically have to implement both, and you have to use explicit interface implementation too, given that both define a parameterless GetEnumerator
method. As IEnumerator<T>
extends IEnumerator
too, it's normally something like this:
public IEnumerator<T> GetEnumerator() { // Return real iterator } // Explicit implementation of nongeneric interface IEnumerator IEnumerable.GetEnumerator() { // Delegate to the generic implementation return GetEnumerator(); }
On the other hand, with the iterator blocks introduced in C# 2 (with yield return
etc) you rarely need to implement these things entirely by hand, fortunately. You may need to write something like the above, and then use yield return
in the GetEnumerator
method.
Note that IList<T>
does not extend IList
, and ICollection<T>
does not extend ICollection
. That's because it's less type-safe to do so... whereas any generic iterator can be seen as a nongeneric iterator due to the (potentially boxing) conversion of any value to object
, IList
and ICollection
allow values to be added to the collection; and it doesn't make sense to add (say) a string to an IList<int>
.
EDIT: The reason why we need IEnumerable<T>
is so that we can iterate in a type-safe way, and propagate that information around. If I return an IEnumerable<string>
to you, you know that you can safely assume everything returned from it will be a string reference or null. With IEnumerable
, we had to effectively cast (often implicitly in a foreach
statement) each element that was returned from the sequence, because the Current
property of IEnumerator
is just of type object
. As for why we still need IEnumerable
- because old interfaces never go away, basically. There's too much existing code using it.
It would have been possible for IEnumerable<T>
not to extend IEnumerable
, but then any code wanting to make use of an IEnumerable<T>
couldn't call into a method accepting IEnumerable
- and there were a lot of methods like that from .NET 1.1 and 1.0.
One returns an object of type Object, the other returns an object of type T.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With