有关C#短路评估的最佳实践是什么?

时间:2008-12-11 21:41:09

标签: c#

另一个帖子中的答案和后续debate in the comments促使我问:

在C#||中和&&是逻辑运算符的短路版本和&分别。

使用示例:

if (String.IsNullOrEmpty(text1) | String.IsNullOrEmpty(text2) | String.IsNullOrEmpty(text3))
{
    //...
}

if (String.IsNullOrEmpty(text1) || String.IsNullOrEmpty(text2) || String.IsNullOrEmpty(text3))
{
    //...
}

在编码实践方面哪个更好用,为什么?

注意:我确实意识到这个问题与this question类似,但我认为它需要进行特定于语言的讨论。

3 个答案:

答案 0 :(得分:45)

  

在编码实践方面哪个更好用,为什么?

简单回答:始终使用短路版本。根本没有理由不这样做。此外,您可以使代码更清晰,因为您表达了 intent :逻辑评估。使用按位(逻辑)操作意味着您只需要:位操作,而不是逻辑评估(即使MSDN在应用于布尔值时也称它们为“逻辑运算符”)。

此外,由于短路仅评估需要评估的内容,因此通常更快,并且允许编写此类代码

bool nullorempty = str == null || str.Length == 0;

(请注意,为了解决这个特殊问题,已经存在一个更好的函数,即你在问题中也使用过的string.IsNullOrEmpty。)这个代码在按位逻辑运算中是不可能的,因为即使{{1 } str,第二个表达式将被评估,结果为null

编辑:如果想要在逻辑上下文中发生副作用,请仍然不使用按位操作。这是一个太聪明的典型例子。代码的下一个维护者(或者甚至是你自己,几个星期后)看到这个代码会认为“嗯,这个代码可以被清除以使用条件运算符”,从而无意中破坏了代码。我很遗憾谁负责修复这个错误。

相反,如果你必须依赖副作用,请将它们明确化:

NullReferenceException

当然,三行而不是一行。但结果是一个更清晰的代码。

答案 1 :(得分:7)

我将反过来回答这个问题:唯一时间何时使用逻辑运算符?

当我有一系列必须满足的(低成本)条件时,我有时会使用逻辑比较。例如:

bool isPasswordValid = true;

isPasswordValid &= isEightCharacters(password);
isPasswordValid &= containsNumeric(password);
isPasswordValid &= containsBothUppercaseAndLowercase(password);

return isPasswordValid;

在我看来,上述内容比以下内容更具可读性:

return (isEightCharacters(password) &&
        containsNumberic(password)  &&
        containsBothUppercaseAndLowercase(password));

缺点是它有点深奥。

答案 2 :(得分:2)

当您只关心结果并希望尽快知道结果时使用&&||,即使布尔条件不是,也不会出现任何必须发生的副作用满足。也就是说,几乎总是如此。

必须评估每个表达式时使用&|(例如,如果您的表达式有副作用)。但是,既然你不应该有你的程序所依赖的副作用,即使不满足布尔条件也必须发生这种副作用,你可能不应该使用&|

例如,这可能是非常愚蠢的:

if (false & somethingThatUpdatesTheDatabase()) { /* ... */ }