我已经回复了这里的线程(或至少commented)包含这样的代码的答案,但是我想知道编写一系列if
分支是否是好的或坏的形式一个(或多个)分支在其中不执行任何操作,通常是为了消除每个分支中null
的检查。
一个例子(C#代码):
if (str == null) { /* Do nothing */ }
else if (str == "SomeSpecialValue")
{
// ...
}
else if (str.Length > 1)
{
// ...
}
而不是:
if (str != null && str == "SomeSpecialValue")
{
// ...
}
else if (str != null && str.Length > 1)
{
// ...
}
当然,这只是一个例子,因为我倾向于使用更大更复杂的类。在大多数情况下,null
值表示什么也不做。
对我来说,这可以减少我的代码的复杂性,并在我看到它时有意义。那么,这是好还是坏的形式(代码味道,甚至)?
答案 0 :(得分:21)
我更喜欢这样做 -
if (str != null)
{
if (str == "[NULL]")
{
// ...
}
else if (str.Length > 1)
{
// ...
}
}
我认为你总是可以用一个空身“重新编号”一个if
进入它对身体的否定,并且它看起来更好,更有意义。
答案 1 :(得分:6)
我通常会在第一个return
中添加if
或类似内容:
void Foo()
{
if (str == null) { return; }
if (str == "SomeSpecialValue")
{
// ...
}
else if (str.Length > 1)
{
// ...
}
}
如果你不能这样做,因为该函数在if
/ else
之后执行其他操作,我会说是时候重构,并拆分if
/ { {1}}分成一个单独的函数,您可以从中早期返回。
答案 2 :(得分:5)
确实很好避免以下情况,因为它不必要地重新检查其中一个条件(编译器将优化它的事实不是重点 - 它可能会使更多的工作对于那些试图阅读你的代码的人来说:
if (str != null && str == "SomeSpecialValue")
{
// ...
}
else if (str != null && str.Length > 1)
{
// ...
}
但是,按照你的建议行事也很奇怪,如下:
if (str == null) { /* Do nothing */ }
else if (str == "SomeSpecialValue")
{
// ...
}
else if (str.Length > 1)
{
// ...
}
我说这很奇怪,因为它模糊了你的意图而违背了读者的期望。如果你检查一个条件,人们希望你做一些事情,如果它满意 - 但你不是。这是因为你的 intent 实际上不是处理 null条件,而是当你检查实际上的两个条件时避免使用空指针实际上,它不是要处理两个概念状态,而是使用完整性提供(非空输入),而不是像处理三个概念状态那样读取。事实上,计算,你可以说有三种这样的状态是不重要的 - 它不太清楚。
在这种情况下通常的案例方法是Oren A建议的 - 检查null,然后检查结果块中的其他条件:
if (str != null)
{
if (str == "SomeSpecialValue")
{
// ...
}
else if (str.Length > 1)
{
// ...
}
}
这不仅仅是提高可读性的风格,而不是代码嗅觉问题。
编辑:但是,如果您设置为无操作条件,我 非常类似于您包含“不执行任何操作”注释。否则,人们可能会认为你只是忘了填写代码。
答案 3 :(得分:4)
在这种特殊情况下,我会提前返回,它使代码更容易阅读
if (string.IsNullOrEmpty(str)) { return; }
我想提出一个明确的退货声明。
答案 4 :(得分:3)
是这是代码味道。
一个迹象是你想要问这个问题。
另一个迹象是代码看起来不完整 - 好像某些东西应该属于那里。它可能是可读的,但感觉不错。
当读取该代码时,局外人必须停止一秒钟并使用智能来确定代码是否有效/完整/正确/符合预期/形容词。
user359996击中了头上的钉子:
我说这很奇怪,因为它模糊了你的意图并且无视读者的期望。
答案 5 :(得分:2)
你的第一个例子对我来说是完全可读的 - 根本没有气味。
答案 6 :(得分:2)
这一切都取决于背景。如果放置一个空的if语句使代码更具可读性,那就去吧。
答案 7 :(得分:2)
它是可读的,无论它的好坏取决于你想要实现的目标 - 通常长嵌套的“永远存在”类型if
语句是坏的。不要忘记框架中出现的静态字符串方法:string.IsNullOrEmpty()
和string.IsNullOrWhiteSpace()
。
你的if (str == null) { /* Do nothing */ }
行是不寻常的,但确实有一个积极的一点:它让其他开发者事先知道你故意不为这种情况做任何事情,你的意图可能变成你想要的长期if / else if结构不清楚你是否改为
if (str != null)
{
/* carry on with the rest of the tests */
}