Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does IEnumerable<T> inherit from IEnumerable?

This might be a old question: Why does IEnumerable<T> inherit from IEnumerable?

This is how .NET do, but it brings a little trouble. Every time I write a class implements IEumerable<T>, I have to write two GetEnumerator() functions, one for IEnumerable<T> and the other for IEnumerable.

And, IList<T> doesn't inherit from IList.

I don't know why IEnumerable<T> is designed in other way.

like image 360
Morgan Cheng Avatar asked Oct 21 '08 12:10

Morgan Cheng


People also ask

What inherits from IEnumerable?

ICollection inherits from IEnumerable. You therefore have all members from the IEnumerable interface implemented in all classes that implement the ICollection interface.

What is IEnumerable<> in c#?

IEnumerable is an interface defining a single method GetEnumerator() that returns an IEnumerator interface. It is the base interface for all non-generic collections that can be enumerated. This works for read-only access to a collection that implements that IEnumerable can be used with a foreach statement.

Why use IEnumerable in c#?

IEnumerable in C# is an interface that defines one method, GetEnumerator which returns an IEnumerator interface. This allows readonly access to a collection then a collection that implements IEnumerable can be used with a for-each statement.

How to use IEnumerable in vb net?

You can create a class that implements the IEnumerable<T> interface to expose source data as enumerable data. Your class that implements the IEnumerable(T) interface will require another class that implements the IEnumerator<T> interface to iterate through the source data.


2 Answers

Straight from the horse's mouth (Hejlsberg):

Ideally all of the generic collection interfaces (e.g. ICollection<T>, IList<T>) would inherit from their non-generic counterparts such that generic interface instances could be used both with generic and non-generic code. For example, it would be convenient if an IList<T> could be passed to code that expects an IList.

As it turns out, the only generic interface for which this is possible is IEnumerable<T>, because only IEnumerable<T> is contra-variant: In IEnumerable<T>, the type parameter T is used only in "output" positions (return values) and not in "input" positions (parameters). ICollection<T> and IList<T> use T in both input and output positions, and those interfaces are therefore invariant. (As an aside, they would have been contra-variant if T was used only in input positions, but that doesn't really matter here.)

<...snip...>

So, to answer your question, IEnumerable<T> inherits from IEnumerable because it can! :-)

like image 165
Mark Brackett Avatar answered Oct 11 '22 07:10

Mark Brackett


The answer for IEnumerable is: "because it can without affecting type safety".

IEnumerable is a "readonly" interface - so it doesn't matter that the generic form is more specific than the nongeneric form. You don't break anything by implementing both. IEnumerator.Current returns object, whereas IEnumerator<T>.Current returns T - that's okay, as you can always legitimately convert to object, although it may mean boxing.

Compare this with IList<T> and IList - you can call Add(object) on an IList, whereas that may well be invalid for any particular IList<T> (anything other than IList<object> in fact).

Brad Abram's blogged with Anders' answer about this very question.

like image 31
Jon Skeet Avatar answered Oct 11 '22 05:10

Jon Skeet