9

我使用 PredicateBuilder 在这里看到http://www.albahari.com/nutshell/predicatebuilder.aspx,一切都很好,现在我可以生成动态 LINQ to SQL 表达式,但我不明白的是为什么当我在这样的循环上:

var inner = PredicateBuilder.False<MyType>();
foreach (var f in Filtermodel.InstrumentsFilterList.Where(s => s.isActive))
        {
          int temp = f.InstrumentID;
          inner = inner.Or(ud => ud.InstrumentId == temp);
        }

为什么我必须使用那个临时变量?,我尝试使用“f”迭代器变量,但它只获取每次迭代的列表中的最后一个值,就像它通过引用传递一样......

4

2 回答 2

10

因为 PredicateBuilder 正在构建一个表达式,该表达式将在稍后的时间点执行。当编译器为委托生成闭包时,它会找到在当前范围内创建的任何值,并将它们也携带到闭包中。由于 InstrumentID 是一个值类型 (int),初始化和复制该值意味着每个委托/闭包都将携带该值。如果您不每次都创建该值的副本,则表达式将仅具有对 f.InstrumentID 的字面引用,而不是对其基础值的引用。所以稍后,当表达式实际执行时,f.InstrumentID 会被评估,它会像上次设置的那样出来,这是最后一次迭代。

于 2009-10-27T01:50:29.303 回答
2

因为它不是评估条件,而是简单地构建表达式。表达式绑定到 foreach 中定义的变量,在整个循环的执行过程中保留它的引用。使用临时变量重新定义它会强制每个表达式使用不同的变量,这会强制它在每次迭代时引用具有值的实例,而不是让所有迭代都引用单个引用并仅具有最后一次迭代的值。

于 2009-10-27T01:50:51.863 回答