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 return
s 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
T
s and F
s 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 return
s 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
}