尝试理解它的一种方法是从小处着手:基本循环 1-10,增量为 +1。
Func<int,int> basicLoop = null;
basicLoop = n => n < 10 ? basicLoop(n+1) : n;
这很简单 - basicLoop 是基于参数 n 返回 n(对于 n >= 10)或使用递增参数调用自身的函数。所以basicLoop(8) 计算为:
-
basicLoop(8) 8 basicLoop(8+1) 得到结果
-
basicLoop(9) 9 basicLoop(9+1) 得到结果
-
basicLoop(10) 10 == 10,因此返回 n,即 10。
-
basicLoop(9) 得到结果 10(来自 basicLoop(10))并返回它
-
basicLoop(8) 得到结果 10(来自 basicLoop(9))并返回它
现在我们要将条件作为参数传递给循环。这意味着我们的“循环”Func 将需要在每次迭代中传递该条件:
该条件的类型显然是(类似于n<10)-Func<int, bool>。所以现在我们有了一些将Func<int,bool> 作为参数并返回与我们原来的basicLoop 相同的值。因此它将是一个参数和一个结果的Func:
Func<Func<int, bool>, Func<int,int>> condLoop = null;
condLoop 是一个参数的函数 - 所以在定义时我们接受参数:condLoop = (condition) => ...。
我们需要替换原来basicLoop中的条件:n => n < 10 ? ...变成n => condition(n) ? ...。
最后一部分是替换basicLoop(n+1) - 我们有condLoop 函数,当您将条件传递给它时,它返回等效于basicLoop。幸运的是,我们的条件在迭代之间没有改变,我们已经有了它 - condLoop(condition) 相当于 basicLoop。把它们放在一起:
condLoop = (condition) =>
n => condition(n) ?
condLoop(condition) (n + 1) :
n;
跟踪调用condLoop(x => x < 5)(4)
-
condLoop(x => x < 5)(4) - 条件是x => x < 5,n = 4 所以当condition(4) 被调用时 x = 4,4 condLoop 并增加 n - condLoop(x => x < 5)(4 + 1) 以获得结果
-
condLoop(x => x < 5)(5) - 条件是 x => x < 5, n = 5 所以当 condition(5) 被调用时 x = 5, 5 n 这是 5
- 返回
condLoop(x => x < 5)(4) - 作为condLoop(x => x < 5)(5) 的结果返回5
使用类似的逻辑添加函数来增加值 - 现在每次迭代都需要传递 condition 和 increment 函数(c 和 f 在原始帖子中)。