I discovered something very strange that I'm hoping to better understand.
var all = new List<int[]>{
new int[]{1,2,3},
new int[]{4,5,6},
new int[]{7,8,9}
};
all.ForEach(n => n.ForEach(i => Console.WriteLine(i)));
which can be rewritten as:
...
all.ForEach(n => n.ForEach(Console.WriteLine));
How is it possible to leave out the lambda expression parameter (i=>) and still have the current item passed to console.WriteLine?
Thanks for any insight. -Keith
List<T>.ForEach
is looking for anAction<T>
. When you writewhat you have here is one of the members of the method group
Console.WriteLine
playing the role of anAction<T>
. The compiler will look for the best overload ofConsole.WriteLine
that eats instances ofint
. In fact, it will use the overloadConsole.WriteLine(int)
. It will then use this overload to play the role of anAction<int>
.For details on how this is done, see §6.6 of the specification (Method group conversions).
However, when you write
we actually have a very different
Action<int>
In the first case, theAction<int>
wasConsole.WriteLine(int)
. Here, theAction<int>
is equivalent to you having writtenand then
(Of course, the compiler has to go through the same method group process as described above to figure out what is meant by
DoSomething
).The point is that in the first case the
Action<int>
isConsole.WriteLine(int)
. However, in the second case theAction<int>
is a middle man (the lambda expression) that itself will callConsole.WriteLine(int)
.This is less confusing if you consider what is really happening.
You are passing a method to a delegate argument. Most of the time, we think of delegates in the context of events, but they can be parameters to methods as well. It doesn't seem odd when a method is added to an event without arguments, it just is unusual looking when executed in this context.
Before lambdas, you had to do this all the time, and it was such a pain that one would never consider using a library that looked like LINQ. With Lambdas, this is easier to do, but you can always do the old way as well.