1

This subject has been discussed many times and is clear: Is relying on && short-circuiting safe in .NET?

What I cannot find is a clear answer if the short circuit is also reliable when out parameter is used in the right part of the if clause:

int foo; .... if ( false == Int32.TryParse( bar, out foo ) || 0 == foo ) 

When I try this code then it works. But I am just a bit worried if the behavior is reliable, because I don't know how the compiler is translating the code and accessing foo.

My question:

Is the access to foo really done after the TryParse which would consider any changed value or the compiler can sometimes read the value before TryParse [because of some optimizations] and therefore I cannot rely on this code.

2
  • Unless there's a bug on the C# compiler, it will work, if there were a possibility of the variable being accessed before being assigned then the compiler would complain about it. Commented May 11, 2018 at 21:46
  • 1
    @Steve The 2nd condition is very necessary when it could be successfully parsed. Commented May 11, 2018 at 21:52

2 Answers 2

3

Is the access to foo really done after the TryParse which would consider any changed value

Yes, this will be the case.

or the compiler can sometimes read the value before TryParse [because of some optimizations] and therefore I cannot rely on this code.

No, it will not read foo before the call to Int32.TryParse; one being that the logical OR will always evaluate the left side and only evaluates the right side if it's necessary. two, it will not evaluate the right side first because the foo variable is not initialised at that point which would cause a compilation error (assuming it's a local variable).

Sign up to request clarification or add additional context in comments.

2 Comments

The point is that foo is a class member and therefore the compiler never warns regarding uninitialized variable - does it change anything?
@AlBundy doesn't change anything in terms of how the expression is evaluated.
2

You can verify this works by using the new language features in C#:

if (!int.TryParse("0", out int foo) || foo == 0) { //foo == 0 or the tryparse failed //foo still exists here though, so if it fails, it will still == 0 } 

You can see that the declaration of foo happens inside the int.TryParse call, which wouldn't happen if foo == 0 was evaluated first. This is legal syntax in C# 7 and up. Really this is all syntactic sugar for this:

int foo = 0 if (!int.TryParse("0", out foo) || foo == 0) { //foo == 0 or the tryparse failed } 

3 Comments

I like this explanation but unfortunately I am stick to an old C# version due to the used framework.
@AlBundy The framework version and the language version are independent, you can use C# 7.1 and compile against .NET 2.0 if you want.
:-) - I am developing for NinjaTrader 7 and I have to use the C# compiler they provide :-((

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.