We all know and love the foreach keyword in C# and use it for loops every day:
List<int> list = new List<int>(); /* fill the list */ foreach (int i in list) Console.WriteLine(i);
But the generic List<T>
class contains a useful method for small loops, too. The method is called ForEach()
and has only one parameter: an Action<T>
.
delegates: Action<>, Func<> and Predicate<>
The Framework 3.5 defines a few generic delegate types for actions and functions. In this case a function is something that returns a value (think back to your math class) and actions are something that do not return a value but do something (maybe think back to physics class). All these delegates are defined with zero, one, two, three and four parameters:
public delegate voidAction();
public delegate voidAction<T>(T obj);
public delegate voidAction<T1, T2>(T1 arg1, T2 arg2);
public delegate voidAction<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);
public delegate voidAction<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
public delegateTResult Func<TResult>();
public delegateTResult Func<T, TResult>(T arg);
public delegateTResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
public delegateTResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
public delegateTResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
And there is one more delegate. The Predicate<T>
(philosophy class, you know). A predicate comes to a logical decision (true or false; bool return value) based on a single object:
public delegate bool Predicate<T>(T obj);
All these delegates are generic so you can use them in a type save way with the type parameters you need.
Back to the ForEach() method
As I explained above, the ForEach()
method takes an Action<T>
parameter. In my example this is an Action<int>
delegate:
list.ForEach( delegate(int i) {Console.WriteLine(i);} );
This anonymous delegate declaration is not that nice, but we can use Lamda types here:
list.ForEach(i => Console.WriteLine(i));
But let’s take a look at the method we’re calling: void Console.WriteLine(int)
. That is exactly the definition of the needed Action here. So we can write the code line even shorter:
list.ForEach( Console.WriteLine );
I like this code. It is very short, elegant and readable. It says: “For each [entry of] the list: write it out”. Great.
Recent Comments