C# 方法组奇怪

标签 c# lambda method-group

我发现了一些非常奇怪的东西,我希望能更好地理解它。

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/

相关文章:

c# - 如何执行 linq 查询以查找数据集中存在于集合的每条记录中的字段?

c# - 通过 IEnumerable 进行分页

amazon-web-services - 与 azure 相比,安排在 aws 中启动和停止 Ec2 实例?

c++ - 它有什么方法可以将带有捕获参数的lambda存储在指针中

c# - 为什么委托(delegate)必须是静态的?

c# - 创建新的 Azure Service Fabric 有状态服务时出现异常

c# - 将 Windows WPF 桌面应用程序移动到 Windows 应用商店应用程序有哪些以触摸为中心的开发优势?

C# - 使用谓词选择属性

c# - "<"运算符(operator)错误

c# - 为什么 C# 编译器在将方法组作为参数传递时不解析仅返回类型不同的委托(delegate)类型?