本文介绍了C#中Lambda/LINQ表达式的高级函数混淆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不确定如何描述此问题,因此标题可能是错误的.

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 calls basicLoop(8+1) to get result
  • basicLoop(9) 9 < 10, so calls basicLoop(9+1) to get result
  • basicLoop(10) 10 == 10, so returns n which is 10.
  • basicLoop(9) got result 10 (from basicLoop(10)) and returns it
  • basicLoop(8) got result 10 (from basicLoop(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 is x => x < 5, n = 4 so when condition(4) is called x = 4, 4 < 5 is true - calling condLoop with same condition and increased n - condLoop(x => x < 5)(4 + 1) to get result
  • condLoop(x => x < 5)(5) - condition is x => x < 5, n = 5 so when condition(5) is called x = 5, 5 < 5 is false - returning n which is 5
  • back to condLoop(x => x < 5)(4) - returning 5 as result of condLoop(x => x < 5)(5)

使用类似的逻辑加法函数来增加值-现在,在每次迭代中,您都需要传递conditionincrement函数(原始帖子中的cf).

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表达式的高级函数混淆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-13 06:12