简化此功能是否可接受/良好风格:
bool TryDo(Class1 obj, SomeEnum type)
{
if (obj.CanDo(type))
{
return Do(obj);
}
else
{
return false;
}
}
为:
bool TryDo(Class1 obj, SomeEnum type)
{
return obj.CanDo(type) && Do(obj);
}
第二个版本较短但可能不太直观。
答案 0 :(得分:64)
我要编码的是:
return obj.CanDo(type) ? Do(obj) : false;
答案 1 :(得分:24)
带括号的版本:
bool TryDo(Class1 obj, SomeEnum type)
{
if (obj.CanDo(type))
{
return Do(obj);
}
return false;
}
<击> 或者没有括号的版本(在回答评论中是关于它的争论很多):
bool TryDo(Class1 obj, SomeEnum type)
{
/*
* If you want use this syntax of
* "if", this doing this on self
* responsibility, and i don't want
* get down votes for this syntax,
* because if I remove this from my
* answer, i get down votes because many
* peoples think brackets i wrong.
* See comments for more information.
*/
if (obj.CanDo(type))
return Do(obj);
return false;
}
击> <击> 撞击>
你的第一个代码示例更好,但我认为我的版本更好。
第二个版本的可读性不高,使代码难以维护,这很糟糕。
答案 2 :(得分:18)
else
无用,而&&
,无论多么明显,都不如纯文字那么可读。
我更喜欢以下内容:
bool TryDo(Class1 obj, SomeEnum type)
{
if (obj.CanDo(type))
{
return Do(obj);
}
return false;
}
答案 3 :(得分:13)
是
特别是名称类似于您选择的名称,即CanDoSomething
和DoSomething
,对于任何有能力的程序员来说,第二个代码的作用是绝对清晰:“ if并且只有当条件成立时,做一些事情并返回结果“。 “当且仅当”是短路&&
运算符的核心含义。
第一个代码是复杂且不必要的长,而不提供比第二个代码更多的信息。
但总的来说,这两个条件可能不会形成如此亲密的关系(如CanDo
和Do
),最好将它们逻辑分开,因为将它们放在同一条件中可能不会直觉。
很多人声称第一个版本“更加清晰”。我真的很想听听他们的论点。我想不出任何一个。
另一方面,这与密切相关(尽管不是相当相同)代码:
if (condition)
return true;
else
return false;
这应该始终转换为:
return condition;
无异常。对于掌握该语言能力的人来说,它更简洁,更具可读性。
答案 4 :(得分:12)
缩短版本隐藏了Do做某事的事实。看起来你只是在进行比较并返回结果,但实际上你正在进行比较并执行一个动作,并且代码具有这种“副作用”并不明显。
我认为问题的核心在于您返回评估结果和操作的返回代码。如果你以这种方式返回两个评估的结果,我就不会有问题
答案 5 :(得分:7)
另一种可能更具可读性的替代方法是使用条件运算符:
bool TryDo(Class1 obj, SomeEnum type) {
return obj.CanDo(type) ? Do(obj) : false;
}
答案 6 :(得分:6)
第一版更容易阅读,更容易被误解,我认为这在现实代码中很重要。
答案 7 :(得分:6)
我不喜欢这种设计,也许不是因为显而易见的原因。困扰我的是。 return Do(obj); 对我而言,Do函数具有bool返回类型是没有意义的。这是否可以替代推动错误的财产? 很可能这个函数应该是void或返回一个复杂的对象。这种情况应该不会出现。 此外,如果一个bool现在以某种方式有意义,它将来很容易停止有意义。随着代码的更改,需要更多的因子来修复
答案 8 :(得分:5)
在这种情况下,我会选择第一个选项 - 很多更具可读性,而且代码的意图很多更清晰。
答案 9 :(得分:5)
两者都没有,因为当TryDo返回False时,你无法确定它是否是因为 '不能做'或'做错了'。
我完全明白你可以忽略结果,但它表达的方式暗示结果有意义。
如果结果毫无意义,
的意图会更清晰void TryDo(Class1 obj, SomeEnum type)
{
if (obj.CanDo(type))
Do(obj);
return;
}
如果结果确实有意义,那么应该有办法区分两个'假'回报。 I.E.什么'If(!TryDo(x))'意味着?
编辑:换句话说,OP的代码是说'我不会游泳'和'我试图游泳和淹死'一样
答案 10 :(得分:4)
虽然对于一个称职的程序员来说,第二个代码肯定是清楚的,但在更一般的情况下,我会更清楚,更容易地阅读代码,就像任何其他代码一样“如果前提条件满足,请执行操作,否则会失败”风格。
这可以通过以下方式实现:
return obj.CanDo(type)? Do(obj) : false;
或者,
if(obj.CanDo(type)) return Do(obj);
return false;
我觉得这很优越,因为无论返回类型如何,都可以复制相同的样式。例如,
return (array.Length > 1)? array[0] : null;
或者,
return (curActivity != null)? curActivity.Operate() : 0;
同样的样式也可以扩展到没有返回值的情况:
if(curSelection != null)
curSelection.DoSomething();
我的两分钱。
答案 11 :(得分:4)
我不喜欢第二个版本,因为我并不喜欢在条件表达式中利用子表达式求值的顺序。它在子表达式上放置了一个预期的排序,在我看来,它应该具有相同的优先级(即使它们没有)。
与此同时,我发现第一个版本有点臃肿,所以我选择了我认为非常易读的三元解决方案。
答案 12 :(得分:3)
IMO只有第二个功能没有副作用才行。但由于Do()有副作用,我会选择if。
我的指导原则是表达不应该有副作用。调用带副作用的函数时,请使用语句 如果函数返回失败代码,则此准则存在问题。在这种情况下,我接受将该错误代码分配给变量或直接返回它。但我不在复杂表达式中使用返回值。所以也许我应该说只有表达式中最外面的函数调用应该有副作用。
有关详细说明,请参阅Eric Lippert's Blog。
答案 13 :(得分:3)
有些人提到的副作用问题是假的。没有人会对名为“Do”的方法产生副作用感到惊讶。
事实是,你正在调用两种方法。这两种方法都将bool作为返回值。您的第二个选择非常简洁明了。 (虽然我会摆脱外括号,你忘了一个结尾的分号。)
答案 14 :(得分:1)
我认为Class1 Type应该在给定SomeEnum值的情况下确定它是否可以。
我会决定是否可以处理输入以供其决定:
bool TryDo(Class1 obj, SomeEnum type)
{
return obj.Do(type));
}
答案 15 :(得分:1)
对我来说,我更喜欢第二种方法。当涉及简单的条件逻辑时,我的大多数返回bool的方法都以相同的方式缩短。
答案 16 :(得分:1)
我可能会因此而讨厌,但是:
if (obj.CanDo(type)) return Do(obj);
return false;
我不喜欢有一个衬垫的支撑。
答案 17 :(得分:1)
没有。第二个版本
return (obj.CanDo(type) && Do(obj))
依赖于&amp;&amp; amp;的短路行为。运算符是一种优化,而不是控制程序流的方法。在我看来,这与使用程序流的异常(几乎同样糟糕)略有不同。
我讨厌聪明的代码,这是一个理解和调试的婊子。该函数的目标是“如果我们可以这样做,那么执行它并返回结果,否则返回false”。原始代码非常清楚。
答案 18 :(得分:1)
永远不要那样做。保持简单直观。
答案 19 :(得分:1)
已经有好几个好的答案,但我想我会再展示一个(我考虑的)好的,可读的代码的例子。
bool TryDo(Class1 obj, SomeEnum type)
{
bool result = false;
if (obj.CanDo(type))
{
result = Do(obj);
}
return result;
}
根据品味,在if语句的主体周围保留或移除花括号。
我喜欢这种方法,因为它说明结果是false
,除非发生其他事情,我认为它更清楚地表明Do()
正在做某事并返回一个布尔值,{{1}用作返回值。