在foreach循环中使用谓词构建器的麻烦

时间:2011-10-19 02:51:16

标签: c# linq predicatebuilder

我在foreach循环中构建谓词时遇到问题。包含枚举器当前所在值的变量是我需要放在谓词中的东西。

所以,

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);

让我失望。在Predicate中ORed一起使用的表达式基本上都是使用inputEnumerable中的相同t,当然我希望每个表达式ORed进入Predicate以使用与inputEnumerable不同的t。

我在循环之后查看调试器中的谓词,它看起来像IL。无论如何,那里的每个lambda看起来完全一样。

谁能告诉我这里可能做错了什么?

谢谢,

艾萨克

2 个答案:

答案 0 :(得分:4)

问题在于闭包是如何工作的。您必须在本地复制SomeOtherType t实例,如:

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

有关详细信息,请参阅:Captured variable in a loop in C#

答案 1 :(得分:1)

你是closing over the loop variable。为SomeOtherType声明一个局部变量,并在谓词中使用它。

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