FAQ :: Parallel.ForEach and non-generic collections?

Danny Shih

.NET 2.0 introduced Generics to allow enhanced code reusability and type safety.  Since then, generic collections (IEnumerable<T>, List<T>, Dictionary<T>, etc.) have become standard and are recommended over their non-generic counterparts (IEnumerable, ArrayList, HashTable, etc.).  As a result, Parallel.ForEach only supports generic collections, so code like the following will fail to compile.


IEnumerable nonGenericCollection = …;


Parallel.ForEach(nonGenericCollection, currentElement =>




This issue applies to all non-generic collections (pretty much anything that was added before .NET 2.0), but here are some usual suspects that we’ve seen folks run into: XmlNodeList, DataRowCollection, DataTableCollection.  The error message is typically something like the following:

·         “The type arguments for method ‘System.Threading.Tasks.Parallel.ForEach<TSource>) cannot be inferred from the usage. Try specifying the type arguments explicitly.”

·         “The best overloaded method match for ‘System.Threading.Tasks.Parallel.ForEach<object>(System.Collections.Generic.IEnumerable<object>, System.Action<object>)’ has some invalid arguments.”


Fortunately, the workaround is simple.  Since non-generic collections produce objects (IEnumerator.Current returns Object), it is always possible to produce an IEnumerable<Object> from an IEnumerable.  For example:


static IEnumerable<object> Cast(IEnumerable source)


    foreach (object o in source)

        yield return o;



Even more fortunately, LINQ already provides this functionality:


public static IEnumerable<TResult>

    Cast<TResult>(this IEnumerable source);


So we can easily fix the initial example using this Cast extension method.


using System.Linq;


    currentElement =>




Discussion is closed.

Feedback usabilla icon