所以我知道经典的例子就像是
int pivot = 65;
var socialSecurityDrawers = from person in People
where person.Age >= pivot
select person;
pivot = 70;
// Since we raised the retirement age, socialSecurityDrawers has been re-filtered accordingly
但我对如何更新查询pivot
中的变量from person in People where person.Age >= pivot select person
感到困惑。据我所知,编译器将查询视为
var socialSecurityDrawers = People.Where(p => p.Age > pivot);
但是,由于pivot是int
,因此是值类型,我不明白如何将pivot
传入lambda表达式实际上是引用pivot
,除非有一些拳击继续进行。这是怎么回事?如果没有,那么这有点让我想起JavaScript中的hoisting,我想知道这是否是一个很好的类比。
答案 0 :(得分:3)
让我们看看会发生什么。 The compiler generates以下显示类:
[CompilerGenerated]
private sealed class <>c__DisplayClass0_0
{
public int pivot;
internal bool <M>b__0(Person person)
{
return person.Age >= this.pivot;
}
}
将你的方法变成:
C.<>c__DisplayClass0_0 <>c__DisplayClass0_ = new C.<>c__DisplayClass0_0();
IEnumerable<Person> arg_1F_0 = new List<Person>();
<>c__DisplayClass0_.pivot = 65;
arg_1F_0.Where(new Func<Person, bool>(<>c__DisplayClass0_.<M>b__0));
<>c__DisplayClass0_.pivot = 70;
因此,它实际上更新了显示类中的值。构造Enumerable.Where
时,会传递驻留在同一显示类中的委托,这样可以确保在您决定执行查询后更新该值。