4

I'm having problems with one of my LINQ queries, so I made a simplified version of it in LINQPad to help me. Problem is, I don't understand why it's still not doing what I think it should...

var list = "1 2 3 4".Split();
var result = list.FirstOrDefault(x =>
                    x == "3"
                    && true);
result.Dump();

This gives back 3, just like one would assume.
However, when I run this:

var list = "1 2 3 4".Split();
var result = list.FirstOrDefault(x =>
                    x == "3"
                    && false ? false : true);

I get 1 back. The last line is the simplification of the actual code. Both examples should give true on the last line, which would return 3, but the query with the conditional operator is throwing a kink in there.

What am I missing?

Marcus
  • 5,407
  • 3
  • 31
  • 54
  • 1
    +1: Upon initially reading the question, I furrowed my brow and wondered, "What am I missing? Why would you expect to get 1 out of the second example? `x == "3" && false` always evaluates to false..." Failing to think about operator precedence can cut both ways. – Esoteric Screen Name Apr 17 '12 at 20:43

4 Answers4

8

Your test expression is associating like this:

(x == "3" && false) ? false : true

instead of like this:

x == "3" && (false ? false : true)
Wesley Wiser
  • 9,491
  • 4
  • 50
  • 69
2

What you are seeing is due to operator precedence. A fix for you would be to wrap the condition in parens:

x == "3" && (false ? false : true)

&& has a higher precedence than ?:

payo
  • 4,501
  • 1
  • 24
  • 32
1

it counts as (x == "3" && false) ? false : true which is why you have a strange behavior.

Louis Kottmann
  • 16,268
  • 4
  • 64
  • 88
0

I suspect your lambda evaluates to (x == 3 && false) ? false : true which will return the first element because the condition will always evaluate to false. Put parentheses for clearer code.

Roman Royter
  • 1,655
  • 13
  • 28