假设我有两种方法bool Foo()
和bool Bar()
.以下哪项更具可读性?
if(Foo()) { SomeProperty = Bar(); } else { SomeProperty = false; }
要么
SomeProperty = Foo() && Bar();
一方面,我认为短路&&
是一个有用的功能,第二个代码样本要短得多.另一方面,我不确定人们通常习惯于&&
在条件陈述之外看到,所以我想知道是否会引入一些认知失调,这使得第一个样本成为更好的选择.
你怎么看?还有其他影响决策的因素吗?比如,如果&&
表达式长于可以放在屏幕上的一行,我应该更喜欢前者吗?
答案后澄清:
我应该把一些事情包括在答案提出的最初问题中.
Bar()
可能比执行起来更昂贵Foo()
,但这两种方法都不应该有副作用.
这些方法都被更恰当地命名,而不是像这个例子中那样. Foo()
归结为类似CurrentUserAllowedToDoX()
和Bar()
更像是,XCanBeDone()
Eric Lippert.. 93
我同意一般的共识,即Foo()&& 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();
我会选择后者.
我同意一般的共识,即Foo()&& 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();
我会选择后者.
假设您的语言允许,我喜欢这种速记符号:
SomeProperty = Foo() ? Bar() : false;
SomeProperty = Foo() && Bar();
这更具可读性.我看不出有人能坦率地选择另一个人.如果&&表达式长于1行,则将其拆分为2行...
SomeProperty = Foo() && Bar(); -or- SomeProperty = Foo() && Bar();
这几乎不会伤害可读性和理解恕我直言.
这取决于Foo和Bar的作用.
例如,IsUserLoggedIn() && IsUserAdmin()
肯定会更好&&
,但有一些其他组合(我不能想到任何随便)ifs会更好.
总的来说,我会建议&&
.
都不是.我首先重命名SomeProperty,Foo和Bar.
我的意思是,你应该构建你的代码,以清楚地传达你的意图.有了不同的功能,我可能会使用不同的形式.然而,就目前而言,任何一种形式都可以.考虑:
IsFather = IsParent() && IsMale();
和
if (FPUAvailable()) { SomeProperty = LengthyFPUOperation(); } else { SomeProperty = false; }
这里,第一种形式强调逻辑和关系.第二个是强调短路.我绝不会以第二种形式写出第一个例子.我可能更喜欢第二个例子的第二个形式,特别是如果我的目标是明确的话.
重点是,使用SomeProperty和Foo()以及Bar()很难回答这个问题.对于通常情况,有一些好的,通用的答案可以保护&&,但我永远不会完全排除第二种形式.
你认为人们会以何种方式误解第二个?你认为他们会忘记&&短路,并担心如果在第一个错误时调用第二个条件会发生什么?如果是这样,我不会担心 - 他们同样会被以下方面所困惑:
if (x != null && x.StartsWith("foo"))
我不认为很多人会重写为第一种形式.
基本上,我会选择第二个.使用适当的描述性变量名称(和条件),它应该是绝对正常的.
在条件表达式简短且简洁的情况下,就像这种情况一样,我发现第二个更易读.一眼就能看出你在这里想要做什么.第一个例子虽然花了我2次通过来了解发生了什么.