前几日在浏览stackoverflow网站时,偶然看到别人提的“How to avoid ‘if’ chains” 的问题,觉得这是一个编程人员在编程时很容易就碰到的问题,而且我自己在看一些源码时也遇到过这种编程方式,因此,对这个问题进行一点总结。
if嵌套的情况很多,下面列出一些情况,并给出了相对来说比较简洁的书写方式以供参考:
1、使用一个guard来使用代码变得平坦
a、代码如下:
if (ok) { DoSomething(); } else { _log.Error("oops"); return; }
可以替换成:
if (!ok) { _log.Error("oops"); return; } DoSomething(); //notice how this is already farther to the left than the example above
b、代码如下:
ok = DoSomething1(); if (ok) { ok = DoSomething2(); if (ok) { ok = DoSomething3(); if (!ok) { _log.Error("oops"); //Tip of the Arrow return; } } else { _log.Error("oops"); return; } } else { _log.Error("oops"); return; }
可以改写成:
ok = DoSomething1(); if (!ok) { _log.Error("oops"); return; } ok = DoSomething2(); if (!ok) { _log.Error("oops"); return; } ok = DoSomething3(); if (!ok) { _log.Error("oops"); return; } ok = DoSomething4(); if (!ok) { _log.Error("oops"); return; }
2、最后有非条件执行代码的情况,伪代码如下:
bool conditionA = executeStepA(); if (conditionA){ bool conditionB = executeStepB(); if (conditionB){ bool conditionC = executeStepC(); if (conditionC){ ... } } } executeThisFunctionInAnyCase();
函数executeStepX当且仅当前面的条件成立时才执行,而函数executeThisFunctionInAnyCase则在最后必需执行,而不管其它条件是否成立。
a、使用条件与(&&),利用条件短路的特性
if (executeStepA() && executeStepB() && executeStepC()){ ... } executeThisFunctionInAnyCase();
b、使用finally
try { bool conditionA = executeStepA(); if (!conditionA) return; bool conditionB = executeStepB(); if (!conditionB) return; bool conditionC = executeStepC(); if (!conditionC) return; } finally { executeThisFunctionInAnyCase(); }
c、将条件执行用一个函数包起来
void foo() { bool conditionA = executeStepA(); if (!conditionA) return; bool conditionB = executeStepB(); if (!conditionB) return; bool conditionC = executeStepC(); if (!conditionC) return; } void bar() { foo(); executeThisFunctionInAnyCase(); }
d、使用goto语句
int foo() { int result = /*some error code*/; if(!executeStepA()) goto cleanup; if(!executeStepB()) goto cleanup; if(!executeStepC()) goto cleanup; result = 0; cleanup: executeThisFunctionInAnyCase(); return result; }
e、利用条件的传递
bool condition = true; // using only one boolean variable if (condition) condition = executeStepA(); if (condition) condition = executeStepB(); if (condition) condition = executeStepC(); ... executeThisFunctionInAnyCase();
f、使用异常
try { executeStepA(); executeStepB(); executeStepC(); } catch (...) { executeThisFunctionInAnyCase(); }
g、使用假循环
while(true) { bool conditionA = executeStepA(); if (!conditionA) break; bool conditionB = executeStepB(); if (!conditionB) break; bool conditionC = executeStepC(); if (!conditionC) break; break; //important } executeThisFunctionInAnyCase();
h、利用对象的生命周期
class MyContext { ~MyContext() { executeThisFunctionInAnyCase(); } } void MainMethod() { MyContext myContext = new MyContext(); bool conditionA = executeStepA(); if (!conditionA) return; bool conditionB = executeStepB(); if (!conditionB) return; bool conditionC = executeStepC(); if (!conditionC) return; //DoSomethingNoMatterWhat will be called when myContext goes out of scope }
其中,最简单的是利用条件短路,而最复杂的是利用对象的生命周期。总结了这此情况和方法供大家参考,当然,可能还有很多其它的情况和处理方法,希望读者踊跃留言。
怎样避免“if”嵌套
时间: 2024-10-07 22:01:38