What is the best practice concerning C# short-circuit evaluation?
另一个话题的评论中的答案和随后的辩论促使我问:
在C中,和&;分别是逻辑运算符和&;的短路版本。
示例用法:
1 2 3 4 | if (String.IsNullOrEmpty(text1) | String.IsNullOrEmpty(text2) | String.IsNullOrEmpty(text3)) { //... } |
对比:
1 2 3 4 | if (String.IsNullOrEmpty(text1) || String.IsNullOrEmpty(text2) || String.IsNullOrEmpty(text3)) { //... } |
在编码实践中,哪一个更好用?为什么?
注:我确实认识到这个问题与这个问题类似,但我相信它需要一个特定语言的讨论。
In terms of coding practice which is the better to use and why?
简单答案:总是使用短路版本。根本没有理由不这么做。此外,您可以使代码更清晰,因为您表达了您的意图:逻辑评估。使用按位(逻辑)操作意味着您只需要这样做:位操作,而不是逻辑计算(即使当应用于布尔值时,msdn也会将它们称为"逻辑运算符")。
此外,由于短路只评估需要评估的内容,因此它通常更快,并且允许编写以下代码
1 | bool nullorempty = str == null || str.Length == 0; |
(请注意,为了解决这个特定的问题,已经存在一个更好的函数,也就是您在问题中使用的
编辑:如果希望在逻辑上下文中发生副作用,请不要使用按位操作。这是一个典型的太聪明的例子。下一个代码维护者(甚至是你自己,几周后)看到这个代码会想"嗯,这个代码可以清除,使用条件运算符",因此不小心破坏了代码。不管谁负责修理这个虫子,我都很遗憾。
相反,如果你不得不依赖副作用,那么就要把它们明确化:
1 2 3 | bool hasBuzzed = checkMakeBuzz(); bool isFrobbed = checkMakeFrob(); bool result = hasBuzzed || isFrobbed; |
当然,三行而不是一行。结果是代码更加清晰。
我要反过来回答这个问题:我唯一一次使用逻辑运算符是什么时候?
当我有一系列必须全部满足的(低成本)条件时,有时会使用逻辑比较。例如:
1 2 3 4 5 6 7 | bool isPasswordValid = true; isPasswordValid &= isEightCharacters(password); isPasswordValid &= containsNumeric(password); isPasswordValid &= containsBothUppercaseAndLowercase(password); return isPasswordValid; |
在我看来,上述内容比:
1 2 3 | return (isEightCharacters(password) && containsNumberic(password) && containsBothUppercaseAndLowercase(password)); |
缺点是它有点深奥。
当您只关心结果并希望尽快知道结果时,使用
当必须计算每个表达式时(例如,如果表达式有副作用),请使用
例如,这可能非常愚蠢:
1 | if (false & somethingThatUpdatesTheDatabase()) { /* ... */ } |