c#延期评估和返回值

use*_*871 3 c# if-statement return func deferred

考虑到下面的例子,我很困惑为什么第一个例子的结果是4,8,6,第二个例子是4,8,3?对我来说,在第一个例子中,只评估succ(3)和dub(4),y应该是3?有人可以帮忙解释它是如何工作的吗?非常感谢!

例一:

public class Hello {
   public static void Main(string[] args) {
     int y = 0;
     Func<int,bool> even = (n) => { return n%2 == 0; }; 
     Func<int,int> dub = (n) => { y += 2; return n + n; };
     Func<int,int> succ = (n) => { y += 1; return n + 1; };

     Func<bool, int, int, int> if1 = (c, t, f) => c? t: f;

     y = 0;
     var a1 = if1(even(3), dub(3), succ(3));
     var a2 = if1(even(4), dub(4), succ(4)); 
     Console.WriteLine("{0} {1} {2}", a1, a2, y);   
   }
 }
Run Code Online (Sandbox Code Playgroud)

第二个例子:

public class Hello {
public static void Main(string[] args) {
  int y = 0;
  Func<int,bool> even = (n) => { return n%2 == 0; }; 
  Func<int,int> dub = (n) => { y += 2; return n + n; };
  Func<int,int> succ = (n) => { y += 1; return n + 1; };

  Func<Func<int,bool>, Func<int,int>, Func<int,int>, Func<int,int>> if2 = (c, t, f) => (n) => { if (c(n)) return t(n); else return f(n); };

   y = 0;
   Func<int,int> x = if2(even, dub, succ); 
   var c1 = x(3);
   var c2 = x(4);
   Console.WriteLine("{0} {1} {2}", c1, c2, y);
 }
}
Run Code Online (Sandbox Code Playgroud)

ang*_*son 5

你混淆了两件不同的事情:

  • 条件运算符
  • 方法参数

在调用方法之前,所有方法参数都会被计算,即使它们最终没有被使用.

因此,事实上,你正在使用的条件运算里面的方法对参数没有影响,他们都评价.

所以这个电话:

var a1 = if1(even(3), dub(3), succ(3));
Run Code Online (Sandbox Code Playgroud)

将评估以下所有内容:

  • even(3)
  • dub(3)
  • succ(3)

在实际调用该方法之前.如果您没有直接结果返回了一个可以调用以获得结果的方法,那么您将拥有真正的延迟代码(在这种情况下),但我敢说代码会开始变得非常难看.

                                   v---v
Func<int, Func<int>> dub = (n) =>  () => { y += 2; return n + n; };
Func<int, Func<int>> succ = (n) => () => { y += 1; return n + 1; };
Func<bool, Func<int>, Func<int>, int> if1 = (c, t, f) => c ? t() : f();
           ^-------------------^                              ^^    ^^
Run Code Online (Sandbox Code Playgroud)

另外,正如@atlaste在你的问题的评论中所说,调试会揭示它是如何工作的,你会看到在你进入之前if1你会逐步完成所有其他方法.