c#延迟评估和返回值

c#延迟评估和返回值,c#,if-statement,return,deferred,func,C#,If Statement,Return,Deferred,Func,考虑到下面的例子,我不明白为什么第一个例子的结果是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; }

考虑到下面的例子,我不明白为什么第一个例子的结果是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);   
   }
 }
公共类你好{
公共静态void Main(字符串[]args){
int y=0;
Func偶数=(n)=>{返回n%2==0;};
Func dub=(n)=>{y+=2;返回n+n;};
Func-succ=(n)=>{y+=1;返回n+1;};
Func if1=(c,t,f)=>c?t:f;
y=0;
var a1=if1(偶数(3)、dub(3)、succ(3));
var a2=if1(偶数(4)、dub(4)、succ(4));
Console.WriteLine(“{0}{1}{2}”,a1,a2,y);
}
}
第二个例子:

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);
 }
}
公共类你好{
公共静态void Main(字符串[]args){
int y=0;
Func偶数=(n)=>{返回n%2==0;};
Func dub=(n)=>{y+=2;返回n+n;};
Func-succ=(n)=>{y+=1;返回n+1;};
Func-if2=(c,t,f)=>(n)=>{if(c(n))返回t(n);else返回f(n);};
y=0;
Func x=if2(偶数、重复、成功);
var c1=x(3);
var c2=x(4);
Console.WriteLine(“{0}{1}{2}”,c1,c2,y);
}
}

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

  • 条件运算符
  • 方法参数
所有的方法参数在调用方法之前都会被求值,即使它们在方法内部最终没有被使用

因此,在方法中使用条件运算符这一事实与参数无关,它们都是经过计算的

所以这个电话:

var a1 = if1(even(3), dub(3), succ(3));
将评估以下所有内容:

  • 偶数(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();
           ^-------------------^                              ^^    ^^
v--v
Func dub=(n)=>()=>{y+=2;返回n+n;};
Func-succ=(n)=>()=>{y+=1;返回n+1;};
Func if1=(c,t,f)=>c?t():f();
^-------------------^                              ^^    ^^

此外,正如在对您的问题的评论中所说,调试将揭示这是如何工作的,您会看到,在进入
if1
之前,您将逐步完成所有其他方法。

您是否尝试过使用调试器逐步完成它?继续按F11,您将得到您的答案:-)它被称为条件运算符。谢谢!我现在没有调试器。。我用了Dump(),但没什么用。我能问一下例子和例子一有什么不同吗?对我来说,它们只是不同的语法。@user3735871您的示例并不延迟调用参数函数,而Lasse的则延迟调用。Lasse正在传递函数,而您正在传递函数的返回值-这意味着他可以随意评估函数,而在您的情况下,在将其返回值传递给
if1
函数之前,必须对函数进行评估。调用Lasse的
if1
时,您会执行类似
if1(偶数(3),()=>dub(3),()=>suc(3))
-注意包装功能。您可能还想将第一个参数更改为
Func
,但既然
甚至是
都是纯的,那就没关系了。@Luaan谢谢!您的意思是,在上面的示例中,因为它在
if2
处传递函数,所以在
var c1=x(3)
处,只有一个函数(在本例中为succ)将被计算?@user3735871是的,因为您传递的是函数本身,而不是它的返回值。函数的求值仅在执行
t()
时发生-与任何其他方法调用一样。