Calling methods inside if() - C#
Asked Answered
H

10

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

Harrier answered 23/2, 2009 at 21:6 Comment(0)
P
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.

Phytoplankton answered 23/2, 2009 at 21:16 Comment(3)
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)Gasser
Huh? & was made for bitwise ANDing. Interesting side effect, though.Immutable
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).Phytoplankton
A
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
}
Alfilaria answered 23/2, 2009 at 21:9 Comment(6)
Why would the first option be cleaner? If I need the check only once, why bother writing an extra function for it?Aret
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.Alfilaria
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.Maculation
I, too, find this clearer, assuming that AllActive() is a useful & descriptive name.Smearcase
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.Alfilaria
This is classic martin fowler refactoringNewmark
K
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.

Knelt answered 23/2, 2009 at 21:11 Comment(6)
I disagree. Not knowing how the boolean operators work is no excuse for replacing with less readable code.Immutable
I agree with spoulson. Taking advantage of short-circuit evaluation is a very common idiom, reads better, and shouldn't confuse anyone.Adala
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.Angevin
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.Angevin
Unless I'm mistaken, the second example will only execute Method2() if Method1() returns true... isn't that just short circuiting?Pablo
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.Negotiable
G
2

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

Grau answered 23/2, 2009 at 21:38 Comment(0)
D
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.

Dramatist answered 23/2, 2009 at 21:45 Comment(1)
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.Maculation
L
1

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

Lexielexigraphy answered 23/2, 2009 at 21:12 Comment(0)
C
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.

Chemush answered 23/2, 2009 at 21:13 Comment(1)
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.Chemush
G
0

Nothin' wrong.

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

Gandzha answered 23/2, 2009 at 21:8 Comment(2)
aw come on, I always call my methods Method_MethodNr_MethodFlavor_MethodColor_MethodShapeTriptolemus
Who needs a stinking class diagram. I'm dogmatic about using cocktail napkins, or pretzels and peanuts to model my systems.Maculation
W
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.
Waverley answered 23/2, 2009 at 22:35 Comment(0)
F
-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

Fiend answered 23/2, 2009 at 22:24 Comment(5)
'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.Coffey
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.Entwine
@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 msdn.microsoft.com/en-us/library/2tb15w2z.aspxFiend
@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! visualbasic.about.com/od/usingvbnet/l/bldykvbnetlogop.htm In VB.Net, And evaluates both expressions regardless, while AndAlso works like &&Fiend
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 betterFiend

© 2022 - 2024 — McMap. All rights reserved.