Foreach loops are rather convenient. In most cases, it's cleaner to write:
var list = new List { 5, 2, 3, 10, 9 };
foreach(var item in list)
{
doSomething(item);
}
Rather than:
var list = new List<int> { 5, 2, 3, 10, 9 };
for(int i = 0; i < list.Count; i++)
{
doSomething(list[i]);
}
...which only works with collections that implement ICollection. Say you wanted to perform some action that required a reference to the item and an index or counter associated with the item. You'd have a separate counter variable, which is slightly messy:
var list = new List<int> { 5, 2, 3, 10, 9 };
int count = 0;
foreach(var item in list)
{
Console.WriteLine(String.Format("Item {0} has index of {1}.", item, count));
count++;
}
Using extension methods in C# 3.0, we can extend IEnumerable to have an "indexed" foreach that supplies us with an index. The following extension method lets us do just that.
public static void ForEach<T>(this IEnumerable<t> self, Action<T, int> action)
{
int index = 0;
foreach (var item in self)
{
action(item, index);
index++;
}
}
Then, our foreach can be rewritten:
var list = new List<int> { 5, 2, 3, 10, 9 };
list.ForEach(delegate(int item, int index)
{
Console.WriteLine(String.Format("Item {0} has index of {1}.", item, index));
});
It can be made more compact using lambda expressions:
var list = new List<int> { 5, 2, 3, 10, 9 };
list.ForEach((item, index) =>
{
Console.WriteLine(String.Format("Item {0} has index of {1}.", item, index));
});
We can also define an extension method for the non-generic IEnumerable interface:
public static void ForEach(this IEnumerable self, Action<Object, int> action)
{
int index = 0;
foreach (var item in self)
{
action(item, index);
index++;
}
}