views:

489

answers:

4

In the example below, if client code using GetPeople wanted to print the name and age of each person to the console, it would have to use reflection (I suppose) to determine that query contained an IEnumerable(Of Person) and then cast it as such to get at its properties.

Public Function GetPeople() As IEnumerable
    Dim query = From p As Person In People.AsEnumerable() _
                Select p
    Return query
End Function

The generic form of IEnumerable seems much more informative and useful to clients:

Public Function GetPeople() As IEnumerable(Of Person)
    Dim query = From p As Person In People.AsEnumerable() _
                Select p
    Return query
End Function

I am sure there is a reason - so, why would IEnumerable ever be favored over IEnumerable(Of T)?

Thanks.

+8  A: 

Never, as far as I can see. IEnumerable<T> inherits IEnumerable, so exposing IEnumerable<T> communicates what you know about T to the caller, while still allowing functions written before generics to use the collection.

The reason non-generic IEnumerable exists is historical.

Doug McClean
Generally, I implement IEnumerable.GetEnumerator() as an explicit interface implementation, and have IEnumerable<T>.GetEnumerator() as the implicit implementation. That way, it is still backwards compatbile (for non-generic code) but using the class normally is fully generic
thecoop
+2  A: 

The only time I've found where I would use IEnumerable over IEnumerable<T> is when dealing with LINQ queries and anonymous objects. Consider the following (contrived) example:

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

IEnumerable<object> GetFirstNames(IEnumerable<Person> people)
{
    return from p in people
           select new
           {
               Name = p.FirstName
           };
}

This will generate the following error:

error CS0266: Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<AnonymousType#1>' to 'System.Collections.Generic.IEnumerable<object>'. An explicit conversion exists (are you missing a cast?)

However, if you change the return type of GetFirstNames() to IEnumerable, it will compile.

Andy
I would personally prefer to leave the signature as IEnumerable<object>, and change the code to select new { Name = p.FirstName }.Cast<object>();
mquander
A: 

If you don't have generics available, i.e. you are using .NET 1.1.

mgroves
A: 

Perhaps, not as a return value. Otherwise, use it whenever possible -- if you can get away with it. It'll make your code more general since IEnumerable is a more general IEnumerable<>.

Foor example, consider a general function that just prints the nun-null values of an IEnumerable.

Ray