0

I have a method that limits the items in a list via LINQ. The list contains items with two boolean properties: bool_a and bool_b. The list contains items where bool_a is true and bool_b is false as well as items where both are false.

My expectation is that once I have limited the list only records where bool_a is false will remain while all items where both bool_a and bool_b are false will be removed. However, I'm finding that all items are being removed. It's as though the AND operator is behaving like an OR.

An example follows. What am I not seeing?

var records = GetRecords();
var count_where_a_before = records .Where(x => x.bool_a); // 100 items
var count_where_ab_before = records .Where(x => x.bool_a && x.bool_b); // 10 items
records = records.Where(x => !x.bool_a && !x.bool_b);
var count_where_a_after = records .Where(x => x.bool_a); // 0 items

As you can see from the above, I've been using counts before and after the where clause to evaluate the list.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
goatshepard
  • 1,063
  • 1
  • 8
  • 18

4 Answers4

3

This line

records = records.Where(x => !x.bool_a && !x.bool_b);

Results in records only having items that have !x.bool_a so logically the next line has no x.bool_a items.

This is true because you state that all x.bool_b are false therefore the statement is really no different to:

records = records.Where(x => !x.bool_a);

EDIT:

you should just be able to use this query if you want all records where bool_a is true and bool_b is false:

records = records.Where(x => x.bool_a && !x.bool_b);
Rob
  • 10,004
  • 5
  • 61
  • 91
  • Thanks Rob. I would expect the Where condition to evaluate all the contained expressions before deciding if a record meets the criteria. – goatshepard Oct 16 '12 at 21:49
  • 1
    @goatshepard - it will but the second part will always evaluate to true because all !x.bool_b are true so the entire statement is always going to hinge of the true/false state of the x.bool_a so it will always return all !x.bool_a – Rob Oct 16 '12 at 22:00
1

If you want to remove all items, where both bool_a and bool_b are false you need to

records = records.Where(x => x.bool_a || x.bool_b);
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
0

The following filter you are using will left only items, where both A and B are FALSE:

records = records.Where(x => !x.bool_a && !x.bool_b);

If you want keep only records where A is TRUE and B is false, use:

records = records.Where(x => x.bool_a && !x.bool_b);

Finally, what you are checking is how many records with A = TRUE:

var count_where_a_after = records .Where(x => x.bool_a);

Make sure this is want you want to check.

Eugene Y.
  • 196
  • 6
-1

Try:

var records = GetRecords().Where(!(x => x.bool_a && x.bool_b)); 
AntLaC
  • 1,215
  • 10
  • 22