2012-10-28 35 views
2

我一直听说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次!懒惰评估全都出错了?

+9

那些是&& &&操作员吗? – Dialecticus

+5

这不是懒惰的评估,它是短路。此外,您正在将位运算符('&')与逻辑运算符('||')混合。 –

回答

34

我一直听说C#使用懒惰评估。

这太过于模糊了,我不同意。如果你说C#中的||&&运算符是短路的,那么只有在第一个操作数不能确定整个结果的情况下评估第二个操作数,我同意它。懒惰评估是一个更广泛的概念 - 例如,LINQ查询使用惰性(或延迟)评估,而不是实际获取任何数据直到使用结果。

您使用的是& operator,这不是短路:

的&运算符计算,无论第一个的价值无论是运营商。

&& operator短路:

操作x && y对应于操作x & y不同之处在于,如果x是假的,y不计算,这是因为与运算的结果为假不管y的值是多少。

替换&&&无处不在您的代码中,您会看到“参数是真实的!”打印8次(不是7 - 再次计算您的评论)。

+0

老实说现在不记得它是否是测试中的&& &&。当我测试它时,会解释意想不到的行为,谢谢! –