notCondition2And3 = !condition2 & !condition3;
// in place of notCondition2And3 should be some meaningful name
// representing what it actually MEANS that neither condition2 nor condition3 were true
And now:
if (condition1 || notCondition2And3)
{
Statement1A;
Statement1B;
return;
}
if (condition2)
{
Statement2;
return;
}
if (condition3)
{
Statement3;
return;
}
As I wrote in my comment to Kieveli's answer, I see nothing wrong about multiple returns in a method, if there is no memory management considerations (as it might be the case in C or C++ where you have to release all resources manually before you leave).
Or another approach still. Here's the decision matrix so that we don't mess it up:
F F F - 1
---------
F F T - 3
---------
F T F - 2
F T T - 2
---------
T F F - 1
T F T - 1
T T F - 1
T T T - 1
Ts and Fs represent the values of condition1, condition2 and condition3 (respectively). The numbers represent the outcomes.
It makes it clear that it's also possible to write the code as:
if (!condition1 && condition2) // outcome 2 only possible for FTF or FTT, condition3 irrelevant
{
Statement2;
return;
}
if (!condition1 && !condition2 && condition3) // outcome 3 only when FFT
{
Statement3;
return;
}
// and for the remaining 5 combinations...
Statement1A;
Statement1B;
Now if we extracted !condition1 (which is present in both ifs), we would get:
if (!condition1)
{
if (condition2) // outcome 2 only possible for FTF or FTT, condition3 irrelevant
{
Statement2;
return;
}
if (condition3) // outcome 3 only when FFT
{
Statement3;
return;
}
}
// and for the remaining 5 combinations...
Statement1A;
Statement1B;
Which is almost exactly what Kieveli suggested, only his disdain for early returns caused his implementation to be buggy (as he noted himself), because it wouldn't do a thing if all 3 conditions were false.
Or, we could revert it like so (this probably wouldn't work in every language - it works in C#, for one, since C# allows for equality comparison between multiple variables), now we're virtually back to the first one:
// note that "condition1" on the right side of || is actually redundant and can be removed,
// because if the expression on the right side of || gets evaluated at all,
// it means that condition1 must have been false anyway:
if (condition1 || (condition1 == condition2 == condition3 == false)) // takes care of all 4 x T** plus FFF (the one special case).
{
Statement1A;
Statement1B;
return;
}
// and now it's nice and clean
if (condition2)
{
Statement2;
return; // or "else" if you prefer
}
if (condition3)
{
Statement3;
return; // if necessary
}
if (condition1)entirely, because it runs the exact same content as theelseblock. Assuming it doesn't cause side effects as jk suggests. That would be pretty 'yuck' indeed. – KChaloux Dec 10 '13 at 13:34if (A) else if (B). Removingif (A)affects the code flow not because checkingAhad some side effect that's missing now. You removed theelseas well. You changed the code semantically. – Konrad Morawski Dec 10 '13 at 15:34condition1may be the return value of a method call that also changes state. Also some other things, like in Java,condition1might be a volatile variable and checking its value results in other changes being seen. – Radiodef Dec 10 '13 at 19:11if-elseblock. If those statements do something else, you may need to redactor their logic to make it clean. This question seems almost too general to be useful- I don't think there exists a single applicable use case. – MirroredFate Dec 10 '13 at 20:55condition1&&condition2? According to the OP, runningstatement2would be the wrong behavior, which is what your version would do. – SailsMan63 Dec 11 '13 at 04:11condition1? As far as I can tell from the original, bothif(condition1)andelseblocks execute the exact same statements. Hence you only need to checkcondition2andcondition3, and simply removecondition1altogether:if (condition2) { Statement2; return; } else if (condition3) { Statement3; return; } Statement1A; Statement1B; return;. There is no need for an emptyif(condition1)block in your refactored code (assuming there are no side effects being removed). – ADTC Sep 10 '14 at 05:08ifblocks which would mean "I only check condition2 and condition3 when condition1 is false. Otherwise I execute 1A and 1B."). But dependent conditions like that could be an indicator of bad code. – ADTC Sep 10 '14 at 05:15