15

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

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
roman m
  • 26,012
  • 31
  • 101
  • 133

10 Answers10

22

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
  • 62,489
  • 19
  • 106
  • 139
  • this is what & and && are made for. it also saves one from a lot of if's (if (foo() && bar() && baz()) myInt++; beats nested if's any day) – jimi hendrix Feb 23 '09 at 21:28
  • 1
    Huh? & was made for bitwise ANDing. Interesting side effect, though. – spoulson Feb 23 '09 at 21:59
  • Back in the C and C++ days yes, but in the C# specification & acts as the Logical AND (where && is the Conditional AND), the bitwise AND (if integer values are used as the operands), and finally it can be used as a unary operator in the unsafe context (to return the address of its operand). – John Rasch Feb 23 '09 at 22:17
20

No, there is 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
  • 14,201
  • 3
  • 42
  • 77
  • Why would the first option be cleaner? If I need the check only once, why bother writing an extra function for it? – Dirk Vollmar Feb 23 '09 at 21:19
  • 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 Feb 23 '09 at 21:23
  • 1
    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 Feb 23 '09 at 21:27
  • I, too, find this clearer, assuming that AllActive() is a useful & descriptive name. – mqp Feb 23 '09 at 21:27
  • 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 Feb 23 '09 at 21:28
  • 1
    This is classic martin fowler refactoring – Mark Rogers Mar 10 '09 at 14:36
2

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
  • 19,439
  • 4
  • 63
  • 103
  • 1
    I disagree. Not knowing how the boolean operators work is no excuse for replacing with less readable code. – spoulson Feb 23 '09 at 21:13
  • I agree with spoulson. Taking advantage of short-circuit evaluation is a very common idiom, reads better, and shouldn't confuse anyone. – AwesomeTown Feb 23 '09 at 21:18
  • 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 Feb 23 '09 at 21:29
  • 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 Feb 23 '09 at 21:31
  • Unless I'm mistaken, the second example will only execute Method2() if Method1() returns true... isn't that just short circuiting? – rmeador Feb 23 '09 at 22:15
  • 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. – Eric Schoonover Feb 23 '09 at 22:30
2

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

Rauhotz
  • 7,914
  • 6
  • 40
  • 44
2

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.

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
  • 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 Feb 23 '09 at 22:00
1

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

Chris Ballance
  • 33,810
  • 26
  • 104
  • 151
1

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
  • 13,367
  • 4
  • 34
  • 46
  • 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 Feb 23 '09 at 21:36
0

Nothin' wrong.

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

Restore the Data Dumps
  • 38,967
  • 12
  • 96
  • 122
0

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
  • 121,657
  • 64
  • 239
  • 328
-3

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

gillonba
  • 897
  • 9
  • 24
  • 'Will future [...] C# compilers work this way?' The ECMA C# spec says "x && y corresponds to [...] x & y, except that y is evaluated only if x is true"; 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 Feb 23 '09 at 22:40
  • 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 Feb 23 '09 at 22:49
  • @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 – gillonba Feb 23 '09 at 23:37
  • @Caleb: When I started my first job out of college I was used to Java, C/C++, and C# so I assumed that VB.Net would work the same. Not so! http://visualbasic.about.com/od/usingvbnet/l/bldykvbnetlogop.htm In VB.Net, And evaluates both expressions regardless, while AndAlso works like && – gillonba Feb 23 '09 at 23:49
  • 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 – gillonba Feb 23 '09 at 23:51