5

I'm having trouble building predicates in a foreach loop. The variable that contains the value the enumerator is currently on is something I need to put in the predicate.

So,

IQueryable query = getIQueryableSomehow();
Predicate = PredicateBuilder.False<SomeType>();
foreach (SomeOtherType t in inputEnumerable)
{
    Predicate = Predicate.Or( x => x.ListInSomeType.Contains(t) )
}
var results = query.Where(Predicate);

is failing me. The expressions ORed together in Predicate basically all use the same t from inputEnumerable, when of course I want each expression ORed into Predicate to use a different t from inputEnumerable.

I looked at the predicate in the debugger after the loop and it is in what looks like IL. Anyways each lambda in there looks exactly the same.

Can anyone tell me what I might be doing wrong here?

Thanks,

Isaac

Isaac Bolinger
  • 7,328
  • 11
  • 52
  • 90

2 Answers2

5

The problem is how closures work. You have to copy the SomeOtherType t instance in a local like:

foreach (SomeOtherType t in inputEnumerable) 
{ 
    SomeOtherType localT = t;
    Predicate = Predicate.Or( x => x.ListInSomeType.Contains(localT) ) 
}

For more information, please see: Captured variable in a loop in C#

Community
  • 1
  • 1
Polity
  • 14,734
  • 2
  • 40
  • 40
1

You're closing over the loop variable. Declare a local variable for your SomeOtherType and use that in your predicate.

foreach (SomeOtherType t in inputEnumerable)
{
    var someOtherType = t;
    Predicate = Predicate.Or( x => x.ListInSomeType.Contains(someOtherType) )
}
Jeff Mercado
  • 129,526
  • 32
  • 251
  • 272
  • thanks, do you know where I can read up more on why the loop variables behave this way? – Isaac Bolinger Oct 19 '11 at 03:03
  • In case you haven't noticed, I had already included a link on it. Eric Lippert's post goes over it in detail on what it is, why it happens, possible "fixes" and why they won't. – Jeff Mercado Oct 19 '11 at 03:14
  • I didn't notice at first. My reading comprehension is poor after 8 hours of coding today. Sorry! I read the link, it's a good explanation. Thanks again! – Isaac Bolinger Oct 19 '11 at 03:22