我对C#的延续性有疑问。我从Tomas Petricek和Jon Skeet着的《真实世界的函数编程》一书中有一个例子。

void StringLengthCont(string s, Action<int> cont) {
   cont(s.Length);
}

void AddLengthsCont() {
 StringLengthCont("One", x1 =>
    StringLengthCont("Two", x2 =>
        Console.WriteLine(x1 + x2)
   ))
}


现在这对我来说很混乱。在这种情况下,我们有一个方法StringLengthCont,它需要一个字符串,s和一个Action<int> cont,然后调用长度为Action<int>s作为参数。

到目前为止,我明白了。但是最后一次调用StringLengthCont的内部lambda是否没有Action<int,int>的签名?在我看来,它需要两个整数,将它们加在一起并返回一个空值。

最佳答案

但是最后一次调用StringLengthCont的内部lambda并不是那样
  有动作的签名吗?


否。会发生以下情况:

您第一次调用StringLengthCont,需要一个Action<int>。传递的实际操作(作为Lambda表达式)再次调用StringLengthCont。第二次,它将“ Two”作为字符串参数传递,并创建一个名为x2的参数,该参数将作为参数传递给StringLengthCont(第二个)。因为x1x2仍然在范围内(这发生在捕获的变量以及编译器处理lambda表达式的方式上),所以我们将它们传递给Console.WriteLine以便打印这两个int的加法。

也许以这种方式看会更清楚:

StringLengthCont("One", new Action<int>(x1 =>
                        StringLengthCont("Two",
                                         new Action<int>((x2) =>
                                         Console.WriteLine(x1 + x2)))));


也许这样:

void AddLengthsCont()
{
    StringLengthCont("One", x1 => CallStringLengthAgain(x1));
}

private void CallStringLengthAgain(int x1)
{
    StringLengthCont("Two", x2 => Console.WriteLine(x1 + x2));
}

09-25 15:50