Given the extra type safety of the generic collection interfaces such as
IEnumerable<T>, the question arises: do you ever need to use the nongeneric
IEnumerable (or ICollection or IList)?
In the case of IEnumerable, you must implement this interface in conjunction with
IEnumerable<T>—because the latter derives from the former. However, it’s very
rare that you actually implement these interfaces from scratch: in nearly all cases,
you can take the higher-level approach of using iterator methods, Collection<T>,
and LINQ.
So, what about as a consumer? In nearly all cases, you can manage entirely with
the generic interfaces. The nongeneric interfaces are still occasionally useful,
though, in their ability to provide type unification for collections across all element
types. The following method, for instance, counts elements in any collection
recursively:
public static int Count (IEnumerable e)
{
int count = 0;
foreach (object element in e)
{
var subCollection = element as IEnumerable;
if (subCollection != null)
count += Count (subCollection);
else
count++;
}
return count;
}
Because C# 4.0 offers covariance with generic interfaces, it might seem valid to
have this method instead accept IEnumerable<object>. This would fail with valuetype
elements, however. It would also fail with legacy collections that don’t implement
IEnumerable<T>— an example is ControlCollection in Windows Forms.