Question about evaluation of IF statements

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hi. I have a question about the evaluation of IF statements when the &&
operator is used. I have been under the assumption that if the first
expression in an IF statement is FALSE it will not evaluate anything after
the && in the same statement.

I have some code that is similar to this:

PaymentEntity pe = GetPaymentEntity();

if (pe.Type == PaymentType.CreditCard &&
((CreditCardPayment)pe).CreditCard.Number > 0)
{
...
}

PaymentEntity - Custom object representing a payment
PaymentType - Custom enum listing the multiple payment types we accept
CreditCardPayment - Custom object representing a credit card payment
(extends PaymentEntity)

I am having a problem where I get an error that states "Specified cast not
valid" when the code is executed with a payment type other than
PaymentType.CreditCard. It appears that an attempt is made to cast pe as a
CreditCardPayment.

My question is, why is the cast even attempted when the first part of the IF
statement evaluates to false?

Thanks.
 
Mike Heard said:
Hi. I have a question about the evaluation of IF statements when the &&
operator is used. I have been under the assumption that if the first
expression in an IF statement is FALSE it will not evaluate anything after
the && in the same statement.

I have some code that is similar to this:

PaymentEntity pe = GetPaymentEntity();

if (pe.Type == PaymentType.CreditCard &&
((CreditCardPayment)pe).CreditCard.Number > 0)
{
...
}

PaymentEntity - Custom object representing a payment
PaymentType - Custom enum listing the multiple payment types we accept
CreditCardPayment - Custom object representing a credit card payment
(extends PaymentEntity)

I am having a problem where I get an error that states "Specified cast not
valid" when the code is executed with a payment type other than
PaymentType.CreditCard. It appears that an attempt is made to cast pe as
a
CreditCardPayment.

My question is, why is the cast even attempted when the first part of the
IF
statement evaluates to false?

Thanks.

I believe the inner parens () are controlling the order of operations. As
the cast is in inner (), that's what is attempted first.
 
Mike Heard said:
Hi. I have a question about the evaluation of IF statements when the &&
operator is used. I have been under the assumption that if the first
expression in an IF statement is FALSE it will not evaluate anything after
the && in the same statement.

Yes, that assumption is correct.
I have some code that is similar to this:

PaymentEntity pe = GetPaymentEntity();

if (pe.Type == PaymentType.CreditCard &&
((CreditCardPayment)pe).CreditCard.Number > 0)
{
...
}

PaymentEntity - Custom object representing a payment
PaymentType - Custom enum listing the multiple payment types we accept
CreditCardPayment - Custom object representing a credit card payment
(extends PaymentEntity)

I am having a problem where I get an error that states "Specified cast not
valid" when the code is executed with a payment type other than
PaymentType.CreditCard. It appears that an attempt is made to cast pe as a
CreditCardPayment.

My question is, why is the cast even attempted when the first part of the IF
statement evaluates to false?

It sounds to me like your pe.Type value is wrong, because C# certainly
does have short-circuiting (which is what you're talking about).

Why do you have one in the first place? Objects already know what kinds
of type they are, so you can just ask them:

if (pe is CreditCardPayment &&
((CreditCardPayment)pe).CreditCard.Number > 0)

or use as:

CreditCardPayment ccp = pe as CreditCardPayment;
if (ccp != null && ccp.CreditCard.Number > 0)
{
...
}

If this doesn't help, could you post a short but complete program which
demonstrates the problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.
 
Jon Skeet said:
Yes, that assumption is correct.


It sounds to me like your pe.Type value is wrong, because C# certainly
does have short-circuiting (which is what you're talking about).

Why do you have one in the first place? Objects already know what kinds
of type they are, so you can just ask them:

if (pe is CreditCardPayment &&
((CreditCardPayment)pe).CreditCard.Number > 0)

or use as:

CreditCardPayment ccp = pe as CreditCardPayment;
if (ccp != null && ccp.CreditCard.Number > 0)
{
...
}

If this doesn't help, could you post a short but complete program which
demonstrates the problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.

Thanks for the reply.

I have stepped into it with the debugger and the pe.Type is set to one of
the other values in the PaymentType enum. Stepping into the statement, the
debugger seems to evaluate the pe.Type == PaymentType.CreditCard first
(because when I step into it I end up in the get method of the Type
property), but then the debugger bombs on the cast.

As far as the other ways you suggested of writing the code, I have changed
the code to keep it from blowing up by just breaking up the single IF
statement into 2 separate IF statements. So the code is working as desired
now, but I wanted to try to find out what was happening with the way it was
written in the first place.

Thanks again for your help.
 
Mike Heard said:
Thanks for the reply.

I have stepped into it with the debugger and the pe.Type is set to one of
the other values in the PaymentType enum. Stepping into the statement, the
debugger seems to evaluate the pe.Type == PaymentType.CreditCard first
(because when I step into it I end up in the get method of the Type
property), but then the debugger bombs on the cast.

I'll believe it when I see it in an example that I can run :)
As far as the other ways you suggested of writing the code, I have changed
the code to keep it from blowing up by just breaking up the single IF
statement into 2 separate IF statements. So the code is working as desired
now, but I wanted to try to find out what was happening with the way it was
written in the first place.

First thing to check is whether you've got & instead of && - that would
bypass short-circuiting.

After that, try to set up a short but complete example, and post it.
 
I think you may be confusing compile errors with run-time errors.
VC# will provide a compile time error when you code an untenable cast.

In general, short-circuiting does not short-circuit compile checks.
e.g, in "x && <non-compilable code>" the compiler will still need to stop
and inform you that <non-compilable code> is not correct.
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB.NET to C# Converter
Instant VB: C# to VB.NET Converter
Instant J#: VB.NET to J# Converter
Clear VB: Cleans up outdated VB.NET code
 
David Anton said:
I think you may be confusing compile errors with run-time errors.
VC# will provide a compile time error when you code an untenable cast.

It sounds like the cast isn't untenable at compile time though.
In general, short-circuiting does not short-circuit compile checks.
e.g, in "x && <non-compilable code>" the compiler will still need to stop
and inform you that <non-compilable code> is not correct.

Indeed - but as the OP has got as far as debugging, I suspect that's
not it. The exception message he gave is also the one given at runtime,
not compile time.
 
Back
Top