Friday, March 23, 2012

System.Collections.Generic.List<T> ForEach method is missing in Windows 8 Runtime

It seems that the handy ForEach method has been removed from the List of T class in the WinRT. According to Wes Haggard of the .NET Framework Bas Class Library (BCL) Team:

“List<T>.ForEach has been removed in Metro style apps. While the method seems simple it has a number of potential problems when the list gets mutated by the method passed to ForEach. Instead it is recommended that you simply use a foreach loop.”

Which is a shame, as I use this method quite a bit to invoke method group calls to do one-time iterations over Lists, like this:

keywordResults.ForEach(this.searchActivity.Keywords.Add);


For situations like this, the mutation issue doesn’t arise and it would be safe to use the ForEach method if it existed. So I did an extension method implementation of the functionality by taking a look at the decompiled code of the method in earlier versions of the .NET Framework:

public void ForEach(Action<T> action)
{
if (action == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
for (int index = 0; index < this._size; ++index)
action(this._items[index]);
}



Using this as a starting point it was fairly easy to come up with an extension method version:

public static void ForEach<T>(this IEnumerable<T> list, Action<T> action)
{
if (action == null)
{
throw new ArgumentNullException("action");
}

foreach (var t in list)
{
action(t);
}
}



Now I can use the extension to give me the same ForEach functionality on IEnumerable objects such as List<T> as I had before.