tags:

views:

800

answers:

10

Imagine this case where I have an object that I need to check a property. However, the object can currently have a null value.

How can I check these two conditions in a single "if" condition?

Currently, I have to do something like this:

if (myObject != null)
{
    if (myObject.Id != pId)
    {
        myObject.Id = pId;
        myObject.Order = pOrder;
    }
}

I would like something like this:

if (myObject != null && myObject.Id != pId)

I want to evaluate the second condition only if the first was true.

Maybe I'm missing something, and that's why I need your help ;-)

+42  A: 
if(myObject != null && myObject.Id != pId)
{
   myObject.Id = pId;
   myObject.Order = pOrder;
}

&& is a short-circuiting logic test - it only evaluates the right-hand-side if the left-hand-side is true. Contrast to "a & b", which always evaluates both sides (and does a bitwise "and")

Marc Gravell
Ok, but I don't want to throw any exception.I only wanted the second condition to be evaluated if the first was true.
Nelson Reis
Refresh the page ;-p
Marc Gravell
Nelson, the code does exactly that. If myObject is null the right part of the if will never be evaluated.
Nils Pipenbrinck
I like that. Guess these are the things you miss when you don't formally learn a language...
lc
Yep... seems like it. Thanks a lot.That saved me a lot of trouble.I know a lot of C# programmers (like me) that don't know this...
Nelson Reis
This answer to this question gets 37 votes???
cletus
@cletus - it is a known problem that simple problems sometimes get lots of votes because lots of people can understand them. Jon's +70 for `for` is another example. Don't worry though; both me and Jon are usually point-saturated (200/day cap), so we don't actually get many points from these votes.
Marc Gravell
+5  A: 
if (myObject != null && myObject.Id != pId)
{
//bla
}

this is safe because operator && is evaluated lazily, meaning that if the LHS is false, the RHS is never evaluated

spender
I can say I've already learned something today. Thanks.
Nelson Reis
+1  A: 
if (myObject != null && myObject.Id != pId)
{
     myObject.Id = pId;
     myObject.Order = pOrder;
}
Jim C
+4  A: 

This code will first check if myObject is not null, in the case that is true it will check the next condition, in the case that is not true it will not check the next condition and not execute the code.

if (myObject != null && myObject.Id != pId)
{
  myObject.Id = pId;
  myObject.Order = pOrder;
}
TomWij
+3  A: 

You've got lots of good answers on how to do it. I just want to put in a warning about how not to do it. Don't wrap the single test for id=pid in a try-catch block. It's wasteful and would involve the introduction of exception checking to catch a non-exceptional condition. It's such a bad idea that I'm not even going to illustrate it with an example.

tvanfosson
Yes, you're right. I wouldn't do that, anyways. First I would check the null value in myObject.
Nelson Reis
+10  A: 

It should be stressed that the short-circuited evaluation of the && in the if() is absolutely guaranteed by the language standards (C, C++, Java and C#). It's been that way since the first edition of K&R's "C Programming Language".

It's not something that you have to worry "Does my compiler implement this?". If definitely does.

James Curran
Thanks, I didn't knew this short-circuited evaluation thing. Seems a little lame now, but its the truth.
Nelson Reis
It's something *a lot* of people don't know about! And many who stumble upon it, think it's a compiler quirk.
James Curran
+1  A: 
if(!(myObject == null || myObject.Id == pId))
{
   myObject.Id = pId;
   myObject.Order = pOrder;
}
sthay
+1  A: 
chillysapien
Nelson Reis
Whoops! Apologies for that. Edited post to reflect that fact
chillysapien
+1  A: 

Since I think it may be helpful to others looking at this question in the future. As stated, using && provides the functionality you want. But, it should also be noted, the functionality you were afraid, that both sides would be evaluated regardless of the result of the first evaluation can be gotten by using & instead of &&. So:

//DO NOT USE THIS CODE
//this will throw an exception if myObject is null
//because myOject.Id != pId will still be evaluated
if(myObject != null & myObject.Id != pId)
{   
   myObject.Id = pId;
   myObject.Order = pOrder;
}

Again, for this example, you DO NOT want this code. I simply wanted to add it to the conversation because there may be cases (though I've never found one) where this is the functionality you want, for example:

//always run both methods
if(MethodA() & MethodB())
{   
   //do stuff only when both methods return true
}
Timothy Carter
Good contribution. Thanks.
Nelson Reis
+1  A: 

Hi Nelson!

You can use & to evaluate two conditions, but if you want to test the second only if the first element is true you can use &&.

In Portuguese we call this: "AND com curto circuito".

if (myObject != null && myObject.Id != pId)

if myObject is false you can't test myObject.Id because myObject is null and you can't access to a property of an null object.

:::::::::::::::::::::::

a b a && b

true true true

true false false

false true false

false false false

:::::::::::::::::::::::

Guilherme Ferreira