3

我一直听说 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));
}

它会打印多少次“argument is true!” 到屏幕上?

我会说7是正确的答案。现在,如果我坚持使用编译器并运行它,它会10多次打印!懒惰的评价到底哪里出错了?

4

1 回答 1

41

我一直听说 C# 使用惰性求值。

这对我来说太模糊了,无法同意。如果您说 C# 中的||and&&运算符是短路的,如果仅从第一个操作数无法确定总体结果,则仅评估第二个操作数,那么我同意它。惰性求值是一个更广泛的概念——例如,LINQ 查询使用惰性(或延迟)求值,在使用结果之前实际上并不获取任何数据。

您正在使用&operator,它不是短路的:

& 运算符会评估两个运算符,而不管第一个运算符的值如何。

&&操作 短路:

操作x && y对应的操作x & y除了如果x为假,y则不求值,因为无论 的值y是什么,AND 操作的结果都是假的。

替换&&&代码中的任何地方,您会看到“参数为真!” 打印 8 次(不是 7 - 再次计算您的评论)。

于 2012-10-28T09:34:26.660 回答