我发现了一些非常奇怪的东西,我希望能更好地理解它。
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)));
可以重写为:
...
all.ForEach(n => n.ForEach(Console.WriteLine));
怎么可能省略 lambda 表达式参数 (i=>) 而仍然将当前项目传递给 console.WriteLine?
感谢任何见解。 -基思
最佳答案
List<T>.ForEach
正在寻找 Action<T>
.当你写作时
n.ForEach(Console.WriteLine);
你这里的是方法组的成员之一 Console.WriteLine
扮演Action<T>
的角色.编译器将寻找 Console.WriteLine
的最佳重载。吃掉 int
的实例.事实上,它会使用重载 Console.WriteLine(int)
.然后它将使用此重载来扮演 Action<int>
的角色。 .
有关如何完成此操作的详细信息,请参阅规范的 §6.6(方法组转换)。
但是,当你写
n.ForEach(i => Console.WriteLine(i));
我们实际上有一个非常不同的Action<int>
在第一种情况下,Action<int>
是Console.WriteLine(int)
.在这里,Action<int>
相当于你写了
public static void DoSomething(int i) {
Console.WriteLine(i);
}
然后
n.ForEach(DoSomething);
(当然,编译器必须经过与上述相同的方法组过程才能弄清楚 DoSomething
的含义)。
重点是在第一种情况下 Action<int>
是 Console.WriteLine(int)
.但是,在第二种情况下 Action<int>
是一个中间人(lambda 表达式),它本身将调用 Console.WriteLine(int)
.
关于C# 方法组奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2230451/