views:

793

answers:

10

I have a couple of methods that return a bool depending on their success, is there anything wrong with calling those methods inside of the IF() ?

//&& makes sure that Method2() will only get called if Method1() returned true, use & to call both methods
if(Method1() && Method2())
{
    // do stuff if both methods returned TRUE
}

Method2() doesn't need to fire if Method1() returns FALSE.

Let me know there's any problem with the code above.

thank you.

EDIT: since there was nothing wrong with the code, I'll accept the most informative answer ... added the comment to solve the "newbie & &&" issue

A: 

Nothin' wrong.

Actually...I wouldn't name them Method1 and Method2. Something more descriptive. Maybe passive sounding too (like StuffHasHappened or DataHasLoaded)

Jason Punyon
aw come on, I always call my methods Method_MethodNr_MethodFlavor_MethodColor_MethodShape
Nailer
@Nailer: Wow...your class diagrams must be really wide...
Jason Punyon
Who needs a stinking class diagram. I'm dogmatic about using cocktail napkins, or pretzels and peanuts to model my systems.
Michael Meadows
+18  A: 

No, nothing wrong with method calls in the if condition. Actually, that can be a great way to make your code more readable!

For instance, it's a lot cleaner to write:

private bool AllActive()
{
    return x.IsActive && y.IsActive && z.IsActive;
}

if(AllActive())
{
    //do stuff
}

than:

if(x.IsActive && y.IsActive && z.IsActive)
{
    //do stuff
}
chills42
Why would the first option be cleaner? If I need the check only once, why bother writing an extra function for it?
0xA3
Mainly clarity, as it is easier to understand what condition you are checking for. "AllActive()" is quicker to comprehend when quickly looking over the code.
chills42
This moves the short-circuit vs full evaluation issue into the AllActive method. I would argue that it only is an improvement if AllActive may have some added value in the subject domain.
Henk Holterman
It adds readability, _and_ allows you to encapsulate more complex compound evaluations in the future. I have had simple if statements turn very ugly very quick, especially if you start combining ifs and ors.
Michael Meadows
mquander
That is true, this is a relatively simple check, the real value of this comes when you have more complex conditions that can be simply understood when looking at the function name.
chills42
This is classic martin fowler refactoring
Mark Rogers
+3  A: 

As useful as they are, sequence points can be confusing. Unless you really understand that, it is not clear that Method2() might not get called at all. If on the other hand you needed BOTH methods to be called AND they had to return true, what would you write? You could go with

bool result1 = Method1();
bool result2 = Method2();
if (result1 && result2)
{
}

or you could go with

if (Method1())
    if (Method2())
    {
    }

So I guess the answer to you question IMHO is, no, it's not exactly clear what you mean even though the behavior will be what you describe.

n8wrl
I disagree. Not knowing how the boolean operators work is no excuse for replacing with less readable code.
spoulson
I agree with spoulson. Taking advantage of short-circuit evaluation is a very common idiom, reads better, and shouldn't confuse anyone.
John Price
While I agree in general, "shouldn't" doesn't always evaluate to "doesn't." His concerns are valid, and I think he was right to raise them, particularly in the context of the OP's question. +1.
Mike Hofer
Further clarification: It's not always clear to newer, less experienced developers. Old hats at short circuiting might feel VERY comfortable with it, giving it no thought at all. Others, not so much. But "newbies," if you will, might inadvertently try to fix the code with unintended results.
Mike Hofer
Unless I'm mistaken, the second example will only execute Method2() if Method1() returns true... isn't that just short circuiting?
rmeador
rmeador you are correct, n8wrl was just giving an example of code that is more readable if you don't understand short circuiting. It is clear that short circuiting is happening in the second example even if you are unaware of the short circuiting concept.
spoon16
+1  A: 

Looks good to me, multiple clauses in the if() block will short circuit if an earlier condition fails.

Chris Ballance
+1  A: 

There shouldn't be any problem.

The normal behavior is that Method1() will execute, and if that returns true Method2() will execute, and depending on what Method2() returns, you may / may not enter the if() statement.

Now, this assumes that the compiler generates code that executes that way. If you want to be absolutely sure that Method2() doesn't execute unless Method1() returns true you could write it like this

if( Method1() )
{
  if( Method2() )
  {
    // do stuff if both methods returned TRUE 
  }
}

But, I've always observed that your code will run as expected, so this is probably not necessary.

TJB
Henk Holterman
Good to know, I had always observed this when using Visual Studio, I wasn't sure if it was standard in the language or not.
TJB
+17  A: 

I'll throw in that you can use the & operator (as opposed to &&) to guarantee that both methods are called even if the left-hand side is false, if for some reason in the future you wish to avoid short-circuiting.

The inverse works for the | operator, where even if the left-hand condition evaluates to true, the right-hand condition will be evaluated as well.

John Rasch
Thanks, I didn't know that.
Jay Riggs
this is what beats nested if's any day)
jimi hendrix
spoulson
John Rasch
+2  A: 

I would only recommend it if the methods are pure (side-effect-free) functions.

Rauhotz
Good point about the side effects
Chris Ballance
+1  A: 

While, as everyone says, there's nothing "wrong" with doing things this way, and in many cases you're doing precisely what the language was designed for.

Bear in mind, however, that for maintainabilities sake, if Method2 has side effects (that is, it changes somethings state) it may not be obvious that this function is not being called (a good programmer will usually know, but even good programmers sometimes have brain farts).

If the short circuited expression has some kind of side effect, it may be more readable to seperate the statements, strictly from a maintenance perspective.

Mystere Man
Good call. It's often best to make these types of evaluation functions completely deterministic. A good way is to make them static, and take only value types as parameters. It's not always possible, but it will guarantee no side effects.
Michael Meadows
A: 

Personally, I would consider

if(Method1() && Method2())
{
    // do stuff if both methods returned TRUE
}

to be a bad practice. Yes, it works in the current environment, but so does

if(Method1())
{
  if (Method2())
  {
    // do stuff if both methods returned TRUE
  }
}

But will it work in ALL environments? Will future, possibly non-Microsoft, C# compilers work this way? What if your next job involves another language where both methods will always be called? I wouldn't rely on that particular construct not because it's wrong, but because it doesn't solve any serious problem, and it may become wrong in the future

rotard
'Will future [...] C# compilers work this way?'The ECMA C# spec says "x a compiler which doesn't obey is as broken as one which enters an 'if' block when the condition evaluates to false instead of true! Not a concern.
Cowan
This same behaviour is also in Java, C and C++. In my experience most languages have a short circuiting and operator. The logical operators should be one of the first things you learn about when learning a new language and learning about them should include their short circuiting behaviour.
Caleb Vear
@Cowan: Non-compliant interpreters and compilers are a fact of life, not an edge condition that can be ignored. Ask a web developer. Or, ask a C++ programmer http://msdn.microsoft.com/en-us/library/2tb15w2z.aspx
rotard
rotard
If you have time to learn all the idiosyncrasies of the language, then you won't be tripped up by little differences, but in the real world you don't always have that option, so the fewer assumptions you have to make when reading or writing a language you don't know the better
rotard
A: 

Looks good to me, but there are some caveats... This is NOT the kind of thing where blanket rules apply.

My guidelines are:

  • If the method names are short, and there are not too many of them, then it's all good.
  • If you have too many statements/method calls inside the if statement, you most likely are comparing more than one "set" of things. Break those "sets" out and introduce temporary variables.
  • "Too many" is subjective, but usually more than around 3
  • When I say "method names are short" I'm talking not just about the names, but the parameters they take as well. Basically the effort required for someone to read it. For example if( Open(host) ) is shorter than if( WeCouldConnectToTheServer ). The total size of all these items is what it comes down to.
Orion Edwards