C# 延迟求值和返回值
c# deferred evaluation and returned values
考虑到下面的示例,我很困惑为什么第一个示例的结果是 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);
}
}
第二个例子:
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);
}
}
你混淆了两个不同的东西:
- 条件运算符
- 方法参数
在调用方法之前评估所有方法参数,即使它们在方法内部最终未被使用。
因此,您在方法中使用条件运算符 的事实与参数无关,它们都会被计算。
所以这个调用:
var a1 = if1(even(3), dub(3), succ(3));
将评估以下所有内容:
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();
^-------------------^ ^^ ^^
此外,正如 @atlaste 在对您的问题的评论中所说,调试将揭示其工作原理,您会看到在进入 if1
之前您将逐步完成所有其他方法.
考虑到下面的示例,我很困惑为什么第一个示例的结果是 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);
}
}
第二个例子:
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);
}
}
你混淆了两个不同的东西:
- 条件运算符
- 方法参数
在调用方法之前评估所有方法参数,即使它们在方法内部最终未被使用。
因此,您在方法中使用条件运算符 的事实与参数无关,它们都会被计算。
所以这个调用:
var a1 = if1(even(3), dub(3), succ(3));
将评估以下所有内容:
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();
^-------------------^ ^^ ^^
此外,正如 @atlaste 在对您的问题的评论中所说,调试将揭示其工作原理,您会看到在进入 if1
之前您将逐步完成所有其他方法.