哪个代码更具可读性?

时间:2009-10-09 16:41:17

标签: c# readability

假设我有两种方法bool Foo()bool Bar()。以下哪项更具可读性?

if(Foo())
{
    SomeProperty = Bar();
}
else
{
    SomeProperty = false;
}

SomeProperty = Foo() && Bar();

一方面,我认为短路&&是一个有用的功能,第二个代码示例要短得多。另一方面,我不确定人们通常习惯于在条件陈述之外看到&&,所以我想知道是否会引入一些认知失调,使第一个样本成为更好的选择。

你怎么看?还有其他影响决策的因素吗?比如,如果&&表达式长于可以放在屏幕上的一行,我应该更喜欢前者吗?


答案后澄清:

我应该把一些事情包括在答案提出的最初问题中。

  • Bar()的执行成本可能比Foo()贵,但这两种方法都不应有副作用。
  • 这些方法的命名更合适,与本例不同。 Foo()归结为类似CurrentUserAllowedToDoX()Bar()更像是XCanBeDone()

21 个答案:

答案 0 :(得分:93)

我同意Foo()&& amp; Bar()形式是合理的,除非Bar()对其副作用及其值有用。

如果Bar()对其副作用及其值有用,我的第一选择是重新设计Bar(),以便产生副作用并计算其值是不同的方法。

如果由于某种原因这是不可能的,那么我会更喜欢原始版本。对我来说,原始版本更清楚地强调对Bar()的调用是对其副作用有用的语句的一部分。后一种形式对我强调Bar()对其价值有用。

例如,给出了

之间的选择
if (NetworkAvailable())
  success = LogUserOn();
else
  success = false;

success = NetworkAvailable() && LogUserOn();

我会接受前者;对我而言,很容易忽视后者的重要副作用。

但是,如果是

之间的选择
if (NetworkAvailable())
  tryWritingToNetworkStorage = UserHasAvailableDiskQuota();
else
  tryWritingToNetworkStorage = false;

tryWritingToNetworkStorage = NetworkAvailable() && UserHasAvailableDiskQuota();

我会选择后者。

答案 1 :(得分:45)

我喜欢这种速记符号,假设您的语言允许:

SomeProperty = Foo() ? Bar() : false;

答案 2 :(得分:19)

SomeProperty = Foo() && Bar();

这更具可读性。我看不出有人能坦率地选择另一个人。如果&&表达式比1行长,将其分成2行...

SomeProperty = 
   Foo() && Bar();

      -or-

SomeProperty = Foo() && 
               Bar();

这几乎不会伤害可读性并理解恕我直言。

答案 3 :(得分:13)

这取决于Foo和Bar的作用。

例如,IsUserLoggedIn() && IsUserAdmin()肯定会更好&&,但还有一些其他组合(我不能想到任何副手)ifs会更好。

总的来说,我会推荐&&

答案 4 :(得分:9)

都不是。我首先重命名SomeProperty,Foo和Bar。

我的意思是,您应该构建代码以清楚地传达您的意图。有了不同的功能,我可能会使用不同的形式。然而,就目前而言,任何一种形式都可以。考虑:

IsFather = IsParent() && IsMale();

if (FPUAvailable()) {
    SomeProperty = LengthyFPUOperation();
} else {
    SomeProperty = false;
}

这里,第一种形式强调逻辑和关系。第二个是强调短路。我绝不会以第二种形式写出第一个例子。我可能更喜欢第二个例子的第二个形式,特别是如果我的目标是明确的话。

重点是,使用SomeProperty和Foo()以及Bar()很难回答这个问题。有一些好的,通用的答案可以捍卫&& amp;对于通常情况,但我永远不会完全排除第二种形式。

答案 5 :(得分:6)

你认为人们会以什么方式误解第二个?你认为他们会忘记&&短路,并担心如果第一个是假的第二个条件被调用会发生什么?如果是这样,我不会担心 - 他们同样会被以下方面所困惑:

if (x != null && x.StartsWith("foo"))

我不认为很多人会重写为第一种形式。

基本上,我会选择第二个。使用适当的描述性变量名称(和条件),它应该是绝对正确的。

答案 6 :(得分:5)

在条件表达式简短且简洁的情况下,就像这种情况一样,我发现第二个更易读。一眼就能看出你在这里想要做什么。第一个例子虽然花了我2次通过来了解发生了什么。

答案 7 :(得分:4)

我会选择第二次,但可能会像第一次一样写,然后我会改变它:)

答案 8 :(得分:3)

第一个,它更可调试

答案 9 :(得分:3)

当我读到第一个时,并不是很明显SomeProperty是一个布尔属性,也没有Bar()返回一个布尔值,直到你读到该语句的else部分。

我个人认为这种方法应该是一种最佳实践:每行代码都应该尽可能地解释,尽可能少参考其他代码

因为语句一要求我引用语句的else部分来插值,SomeProperty和Bar()本质上都是布尔值,我会使用第二个。

在第二部分中,在一行代码中立即显而易见以下所有事实:

  • SomeProperty是布尔值。
  • Foo()和Bar()都返回可以解释为boolean的值。
  • 除非将Foo()和Bar()都解释为true,否则SomeProperty应设置为false。

答案 10 :(得分:1)

等一下。这些陈述甚至不等同,是吗?我已经好几次看了他们,他们没有评价同样的事情。

第一个版本的简写是使用三元运算符,而不是“和”运算符。

SomeProperty = foo() ? bar: false

然而,除了逻辑错误之外,我同意其他所有人认为较短的版本更具可读性。

修改 - 添加

然后,如果我错了并且没有逻辑错误,那么第二种方式更具可读性,因为代码正在做什么非常明显。

再次修改 - 添加更多内容:

现在我明白了。没有逻辑错误。但是,我认为这说明对于我们这些尚未喝咖啡的人来说,较长的版本更清晰。

答案 11 :(得分:1)

能够单独断开任何特定函数调用以及将变量的任何特定设置转换为特定值通常很有用 - 因此,可能有争议的是,我倾向于选择第一个选项。这更有可能允许在所有调试器上进行细粒度断点(在C#的情况下,这不是一个非常大的数字)。

这样,可以在调用Foo()之前设置断点,在调用Bar()(和变量的集合)之前,以及当变量设置为false时 - 显然是相同的断点也可以用来捕获Foo()vs!Foo()的情况,具体取决于你想到的问题。

当这一切都在一条线上时,这并非不可能,但需要注意的是可以用来解决所调查问题的原因。

(C#快速编译,因此重新排列代码通常不是一个大问题,但这会分散注意力。)

答案 12 :(得分:1)

如果第一个版本看起来像这样:

if (Foo() && Bar())
{
    SomeProperty = true;
}
else
{
    SomeProperty = false;
}

或者像这样:

if (Foo())
{
    if (Bar())
       SomeProperty = true;
    else
       SomeProperty = false;
}
else
{
    SomeProperty = false;
}

然后它至少会一致。这样,逻辑比第二种情况更难以理解。

答案 13 :(得分:1)

如果你指出,Bar()有副作用,我宁愿采用更明确的方法。否则有些人可能没有意识到你打算利用短路。

如果Bar()是自包含的,那么我会采用更简洁的方式来表达代码。

答案 14 :(得分:1)

我会选择长版本,因为乍一看它的功能很清楚。在第二个版本中,你需要停下几个secons,直到你意识到&& amp;的短路行为。运营商。它是聪明的代码,但不是可读的代码。

答案 15 :(得分:1)

我认为,最好的方法是使用SomeProperty = Foo() && Bar(),因为它要短得多。我认为任何正常的.NET程序员都应该知道&& -operator是如何工作的。

答案 16 :(得分:0)

在我看来,这归结为有意和清晰。

第一种方法让不经意的观察者清楚你没有执行Bar(),除非Foo()返回true。我知道短路逻辑会阻止Bar()在第二个例子中被调用(我可能会自己这样写)但第一种方式乍看起来更有意。

答案 17 :(得分:0)

AND行为的短路并不是所有语言的标准,所以如果这对我的代码至关重要,我倾向于谨慎地使用它。

我不相信自己在当天第五次切换语言后立即看到了短路。

因此,如果在Foo()返回false时永远不应该调用Boo(),那么我将使用版本#2,如果仅作为防御性编程技术。

答案 18 :(得分:0)

第一种方法更具可读性,但获取更多代码行,第二种方法更有效,无比较,只有一行!我认为第二个更好

答案 19 :(得分:-1)

由于您使用的是c#,我会选择第一个版本或使用三元?:运算符。以这种方式使用&&并不是c#中常见的习惯用语,因此您更容易被误解。在其他一些语言中(Ruby会浮现在脑海中)&&模式更受欢迎,我认为它在这种情况下是合适的。

答案 20 :(得分:-3)

我会说代码是可读的,如果它对于不了解实际编程语言的人来说是可读的,那么代码就像

if(Foo() == true and Bar() == true)
then
    SomeProperty = true;
else
    SomeProperty = false;

更具可读性
SomeProperty = Foo() && Bar();

如果程序员在您不熟悉后一种语法后接管代码,那么将花费他10倍于写出额外几个字符的时间。