我一直听说C#使用懒惰评估。因此,对于某些代码,if (true || DoExpensiveOperation()
将返回true
而不执行DoExpensiveOperation()
。
在面试测试中,我看到了以下问题,
static bool WriteIfTrue(bool argument)
{
if (argument)
{
Console.WriteLine("argument is true!");
}
return argument;
}
static void Main()
{
// 1 0 0 1
WriteIfTrue((WriteIfTrue(false) & WriteIfTrue(true)) || WriteIfTrue(true));
// 1 1 0 1
WriteIfTrue((WriteIfTrue(true) || WriteIfTrue(false)) & WriteIfTrue(true));
// 0 0 0 0
WriteIfTrue((WriteIfTrue(false) & WriteIfTrue(true)) & WriteIfTrue(false));
// 1 1 0 1
WriteIfTrue((WriteIfTrue(true) || WriteIfTrue(false)) & WriteIfTrue(true));
}
打印多少次“论证是真的!”到屏幕?
我会说7
是正确答案。现在,如果我坚持使用编译器并运行它,它会打印10
次!懒惰评价哪里出错?
答案 0 :(得分:37)
我一直听说C#使用懒惰评估。
对于我同意的评论,这太过模糊了。如果您说C#中的||
和&&
运算符是短路的,那么只评估第二个操作数,如果不能仅从第一个操作数确定整体结果,那么 我同意。延迟评估是一个更广泛的概念 - 例如,LINQ查询使用延迟(或延迟)评估,而不是在使用结果之前实际获取任何数据。
您使用的是&
operator,其中未短路:
&无论第一个运算符的值如何,运算符都会对运算符求值。
&&
operator 短路:
操作
x && y
对应于操作x & y
,但如果x
为假,则不评估y
,因为AND操作的结果为假,无论如何y
的价值是什么。
将&
替换为代码中的&&
,您会看到“参数是真的!”打印8次(不是7次 - 再次计算您的评论)。