if/else,好的设计

Cap*_*mic 18 c# if-statement

简化此功能是否可接受/良好的风格:

bool TryDo(Class1 obj, SomeEnum type)
{
    if (obj.CanDo(type))
    {
        return Do(obj);
    }
    else
    {
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

如:

bool TryDo(Class1 obj, SomeEnum type)
{
    return obj.CanDo(type) && Do(obj);
}
Run Code Online (Sandbox Code Playgroud)

第二个版本较短但可以说不太直观.

Kev*_*imm 64

我要编码的是:

return obj.CanDo(type) ? Do(obj) : false;
Run Code Online (Sandbox Code Playgroud)

  • 这是一个漂亮的单线解决方案,但根本不可读. (13认同)
  • @Zann可读性很大程度上取决于练习.对于那些练习阅读过这个操作符的人来说,它是可读的 - 这是许多程序员所拥有的.代码的可读性是一个相当难以实现的目标,因为这...... (9认同)
  • 到目前为止,这是最好的答案.它很短但等同于if/else(不仅在功能上等同,而且在语义上也是如此).我唯一的批评是我会删除多余的括号. (6认同)
  • *请*删除额外的括号 (6认同)
  • 我不明白为什么人们会以三元条件为准.在我看来很好! (3认同)
  • 对,第三种选择. (2认同)
  • jon_darkstar:因为在视觉上,它几乎是透明的.我可以用一个非常简短的关键字来查看一行,比如`if`并轻松识别这些部分,但是`?`和`:`很容易迷失在噪音中,特别是通常需要的所有`()`.我很喜欢`?:`的表达能力(而且,作为一个Lisp和Ruby程序员,我认为if语句根本就是愚蠢的),但我觉得它在视觉上很难读出来?`:` . (2认同)

Svi*_*ack 24

带括号的版本:

bool TryDo(Class1 obj, SomeEnum type)
{
    if (obj.CanDo(type))
    {
        return Do(obj);
    }

    return false;
}
Run Code Online (Sandbox Code Playgroud)

或者没有括号的版本(在回答评论中是关于它的高度争论):

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;
}
Run Code Online (Sandbox Code Playgroud)

你的第一个代码示例更好,但我认为我的版本更好.

你的第二个版本的可读性不好,使代码难以维护,这很糟糕.

  • @Zannjaminderson:这一点值得商榷.没有达成共识,让支撑脱落是不好的.这当然不是"不好的做法".如果有人出现并添加代码,他们也会添加大括号.根据我的经验,忘记这不是一个常见的错误. (7认同)
  • 我最喜欢这个版本.您也可以从if-block中删除大括号以将其压缩一点,但有些人真的不喜欢它. (4认同)
  • @Zann:这需要投票.我不认为这种代码风格不太可接受.事实上,我个人觉得*总是更好*,因为像杰夫阿特伍德一样,我将屏幕空间视为一个房地产,我讨厌用冗余的空行(这里是由闭合支架引入)浪费它. (4认同)
  • 为了便于阅读和维护,将大括号从块中移除通常是不好的做法. (2认同)
  • @Svisstack - 它不太清楚究竟是什么,并且不是没有括号的if块的一部分.此外,如果有人出现并添加了if块的代码但是错过了添加大括号,那么你现在遇到了一个bug. (2认同)

Pau*_*des 18

else是无用的&&,但是很明显,它不像纯文本那样可读.

我更喜欢以下内容:

bool TryDo(Class1 obj, SomeEnum type)
{
    if (obj.CanDo(type))
    {
        return Do(obj);
    }   
    return false;
}
Run Code Online (Sandbox Code Playgroud)


Kon*_*lph 13

是.

尤其是类似于您选择的名称,即名称CanDoSomethingDoSomething它是绝对清楚任何有能力的程序员什么第二个代码所做的:" 当且仅当该条件成立,做一些事情,返回的结果"."当且仅当"是短路&&运营商的核心含义.

第一个代码是复杂的并且不必要地长,而不提供比第二个代码更多的信息.

但总的来说,这两个条件可能不会形成如此亲密的关系(如在CanDo和中Do)并且最好将它们逻辑地分开,因为将它们置于相同的条件中可能并不具有直观意义.

很多人都声称第一个版本"更加清晰".我真的很想听听他们的论点.我什么都想不到.

在另一方面,有这密切相关的(虽然不是相同)的代码:

if (condition)
    return true;
else
    return false;
Run Code Online (Sandbox Code Playgroud)

这应该总是转变为:

return condition;
Run Code Online (Sandbox Code Playgroud)

没有例外.对于掌握该语言能力的人来说,它更简洁,更具可读性.

  • 是的,但OP想要返回别的东西,而不是条件结果. (4认同)
  • @kaliatech:在"完全胜任"和理解语言基础之间有很长的路要走.我(强烈地)争辩说,我们不能总是在清洁代码中迎合初学者,因为结果将是复杂的,复杂的并且最终难以为专业人士维护.如果没有任何其他原因,那么因为代码大小.是的,代码大小*确实很重要. (4认同)

Kev*_*van 12

缩短版本隐藏了Do做某事的事实.看起来你只是在进行比较并返回结果,但实际上你正在进行比较并执行一个动作,并且代码具有这种"副作用"并不明显.

我认为问题的核心在于您返回评估结果和操作的返回代码.如果你以这种方式返回两个评估的结果,我就不会有问题了


Guf*_*ffa 7

另一个可能更具可读性的替代方法是使用条件运算符:

bool TryDo(Class1 obj, SomeEnum type) {
  return obj.CanDo(type) ? Do(obj) : false;
}
Run Code Online (Sandbox Code Playgroud)

  • 只有在代码库中大量使用条件运算符时. (3认同)

kal*_*ech 6

第一个版本更容易阅读,更容易被误解,我认为这在现实世界的代码中很重要.


And*_*rey 6

我不喜欢这种设计,也许不是因为显而易见的原因.困扰我的是.return Do(obj); 对我而言,Do函数具有bool返回类型是没有意义的.这是否可以替代推动错误的财产?很可能这个函数应该是void或返回一个复杂的对象.这种情况应该不会出现.此外,如果一个bool现在以某种方式有意义,它将来很容易停止有意义.随着代码的更改,需要更多的因子来修复

  • 绝对不同意.一种具有副作用并返回bool的方法是完全正常的并且一直出现.例如,考虑`bool HashSet <T> .Add()`.你的批评对OP的代码结构做了太多的假设 - 从我们看到的很少,它是完全合理的. (3认同)

Ode*_*ded 5

在这种情况下,我会去的第一个选项-这是很多更具可读性和代码的意图是多少清晰.

  • 其他是不必要的. (3认同)

smi*_*man 5

也不是,因为当TryDo返回False时,您无法确定它是否是因为'Not CanDo'或'Do return False'.

我完全理解你可以忽略结果,但它表达的方式暗示结果有意义.

如果结果毫无意义,那么意图就会更加清晰

void TryDo(Class1 obj, SomeEnum type)
{
    if (obj.CanDo(type))
        Do(obj);
    return;
}
Run Code Online (Sandbox Code Playgroud)

如果结果确实有意义,那么应该有一种方法来区分两个"错误"的回报.IE"If(!TryDo(x))" 什么意思

编辑:换句话说,OP的代码是说'我不会游泳'与'我试图游泳和淹死'相同