问题描述
不确定如何描述此问题,因此标题可能是错误的.
Unsure how to describe this question so the title might be wrong.
我正在阅读一些代码示例,并对以下返回函数感到困惑:
Am reading over some code examples and am confused over the following return function:
Func<Func<int , bool>, Func<int , int>, Func<int , int>> Loop = null ;
Loop = (c , f ) => n => c(n) ? Loop(c , f ) ( f (n)): n;
Func<int , int> w = Loop(n => n < 10 , n => n + 2);
var r = w(2);
var s = w(3);
Console . WriteLine ("{0} {1}" , r , s );
我了解到c(n)的计算结果为true时,此函数将返回Loop,但我不了解Loop(c,f)(f(n))的计算方式-它们是否都被传递回Loop中?我曾尝试在Linqpad中运行转储,但我不知道该位的运行方式.
I understand that this function is returning the Loop when c(n) evaluates to true, but I don't understand how Loop(c,f) (f(n)) evaluates - are they both being passed back into Loop? I have tried running dumps in Linqpad and I just don't get how that bit is running.
任何帮助将不胜感激,了解这可能是一个愚蠢的问题!
Any help would be appreciated, understand this is probably a dumb question!
推荐答案
尝试了解它的一种方法是从小做起:以+1的增量进行基本循环1-10.
One way to try to understand it is start small: have basic loop 1-10 with +1 increment.
Func<int,int> basicLoop = null;
basicLoop = n => n < 10 ? basicLoop(n+1) : n;
这非常简单-basicLoop
是基于参数n
返回n
(对于n> = 10)或使用递增参数进行调用的函数.因此basicLoop(8)
的计算公式为:
That's pretty simple - basicLoop
is function that based on parameter n
returns n
(for n >= 10) or calls itself with incremented parameter. So basicLoop(8)
is computed as:
-
basicLoop(8)
8< 10,所以调用basicLoop(8+1)
以获得结果 -
basicLoop(9)
9< 10,所以调用basicLoop(9+1)
以获得结果 -
basicLoop(10)
10 == 10,因此返回n
,即10. -
basicLoop(9)
获得结果10(来自basicLoop(10)
)并返回 -
basicLoop(8)
获得结果10(来自basicLoop(9)
)并返回
basicLoop(8)
8 < 10, so callsbasicLoop(8+1)
to get resultbasicLoop(9)
9 < 10, so callsbasicLoop(9+1)
to get resultbasicLoop(10)
10 == 10, so returnsn
which is 10.basicLoop(9)
got result 10 (frombasicLoop(10)
) and returns itbasicLoop(8)
got result 10 (frombasicLoop(9)
)and returns it
现在,我们希望将条件作为参数传递给循环.这意味着我们的循环" Func
将需要在每次迭代中传递该条件:
Now we want to pass condition as parameter to the loop. That means our "loop" Func
will need to pass that condition around on every iteration:
该条件的类型显然是(类似于n<10
)-Func<int, bool>
.因此,现在我们有了以Func<int,bool>
作为参数并返回与原始basicLoop
相同的值的东西.因此,它将是一个参数和一个结果的Func
:
Type of that condition is clearly (similar to n<10
) - Func<int, bool>
. So now we have something that takes Func<int,bool>
as argument and returns same value as our original basicLoop
. Hence it will be Func
of one argument and one result:
Func<Func<int, bool>, Func<int,int>> condLoop = null;
condLoop
是一个参数的函数-因此在定义时我们采用参数:condLoop = (condition) => ...
.
condLoop
is function of one argument - so when defining we take argument: condLoop = (condition) => ...
.
我们需要替换原始basicLoop
中的条件:n => n < 10 ? ...
变为n => condition(n) ? ...
.
We need to replace condition in our original basicLoop
: n => n < 10 ? ...
becomes n => condition(n) ? ...
.
最后一部分是替换basicLoop(n+1)
-我们具有condLoop
函数,当您将条件传递给它时,该函数返回与basicLoop
等价的内容.幸运的是,我们的条件在两次迭代之间不会改变,并且已经有了--condLoop(condition)
等效于basicLoop
.整合在一起:
The last part is replacing basicLoop(n+1)
- we have condLoop
function that returns equivalent of basicLoop
when you pass condition to it. Fortunately our condition does not change between iterations and we already have it - condLoop(condition)
is equivalent of basicLoop
. Getting it all together:
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< 5是正确的-在相同条件下调用condLoop
并增加n-condLoop(x => x < 5)(4 + 1)
以获得结果 -
condLoop(x => x < 5)(5)
-条件为x => x < 5
,n = 5,所以当condition(5)
被称为x = 5时,5< 5为假-返回n
为5 - 返回
condLoop(x => x < 5)(4)
-由于condLoop(x => x < 5)(5)
返回5
condLoop(x => x < 5)(4)
- condition isx => x < 5
, n = 4 so whencondition(4)
is called x = 4, 4 < 5 is true - callingcondLoop
with same condition and increased n -condLoop(x => x < 5)(4 + 1)
to get resultcondLoop(x => x < 5)(5)
- condition isx => x < 5
, n = 5 so whencondition(5)
is called x = 5, 5 < 5 is false - returningn
which is 5- back to
condLoop(x => x < 5)(4)
- returning 5 as result ofcondLoop(x => x < 5)(5)
使用类似的逻辑加法函数来增加值-现在,在每次迭代中,您都需要传递condition
和increment
函数(原始帖子中的c
和f
).
With similar logic adding function that increments value - on every iteration now you need to pass condition
and increment
function (c
and f
in original post).
这篇关于C#中Lambda/LINQ表达式的高级函数混淆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!