Why Does Ienumerable<T> Inherit from Ienumerable

Why does IEnumerableT inherit from IEnumerable?

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! :-)

Why Enumerable doesn't inherits from IEnumerableT

The Select(), Where() etc are "extension methods". They need to be defined "elsewhere" as an interface can't supply an implementation of methods.

You can recognize extension methods by the keyword "this" in the argument list. For instance:

public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate
)

can be used as if it's a method on an IEnumerable<TSource> with one parameter: Func<TSource, bool> predicate.

Why IListT inherits IEnumerableT and IEnumerable again

The documentation is generated that way so you can see what interfaces a type implements without having to follow transitive links through the interface inheritance hierarchy.

Inheriting from IEnumerable

You don't inherit from IEnumerable. That is an interface. You can implement interfaces.

The error message you show leads me to suspect that you are implementing IEnumerable.GetEnumerator() which returns IEnumerator (a non-generic interface) but attempting to use the generic, IEnumerator<T> interface in your code.

The code in your link indeed shows the implementation of a generic interface

public IEnumerator <T> GetEnumerator()
{
return Items.GetEnumerator();
}

Why does ICollectionT implement both IEnumerableT and IEnumerable

The non-generic interface is for backward compatibility. If you write code using generics and want to pass your collection to some module written in .NET 1.0 (which doesn't have generics) you still want this to succeed, and you want the old method to be able to iterate through it.

Inheriting IEnumerablestring cause error CS0738

IEnumarable< T> inherits IEnumarable. So you need to implement IEnumerator IEnumerable.GetEnumerator() method also.

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

Also, your code won't compile, because GetEnumerator method should return IEnumerator instead of
IEnumarable. Use GetEnumarator method to get IEnumerator.

public class TestEnumarable : IEnumerable<string>
{
public IEnumerator<string> GetEnumerator()
{
LinkedList<string> a = new LinkedList<string>();

return a.GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}

CollectionT: why does it implement both IEnumerable and IEnumerableT?

It says it implements IEnumerable because it implements IEnumerable.

IEnumerable<T> inherits IEnumerable, but it can obviously provide no implementation. Classes that implement IEnumerable<T> must also implement IEnumerable, whether or not they explicitly state that they do so.

class Foo : IEnumerable<T> 
class Foo : IEnumerable<T>, IEnumerable

With either case, you implement the members of both interfaces. The second class definition simply makes it obvious for those looking at the class and/or the documentation, which is a good thing. An inexperienced or otherwise uninformed reader might not know that IEnumerable<T> brings IEnumerable along with it. They might might not know that a class that implements IEnumerable<T> can be used where an IEnumerable is expected. This simply provides a bit more information to the reader, which can only be a good thing on average.



Related Topics



Leave a reply



Submit