user5572578
user5572578

Reputation: 159

How do LINQ queries update if variables they include are updated?

So I know the classic example is something like

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

But I'm confused at how the variable pivot in the query from person in People where person.Age >= pivot select person is updated. I understand that the query is thought of by the compiler as

var socialSecurityDrawers = People.Where(p => p.Age > pivot);

However, since pivot is an int and therefore a value type, I don't understand how passing in pivot into a lambda expression essentially makes it a reference to pivot unless there's some boxing that goes on. Is that what happens? If not, then this kinda reminds me of hoisting in JavaScript and I'm wondering if that's a good analogy.

Upvotes: 3

Views: 101

Answers (1)

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149558

Lets see what happens. The compiler generates the following display class:

[CompilerGenerated]
private sealed class <>c__DisplayClass0_0
{
    public int pivot;
    internal bool <M>b__0(Person person)
    {
        return person.Age >= this.pivot;
    }
}

And turns your method into:

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;

Thus, it actually updates the value inside the display class. When the Enumerable.Where is constructed, it is passed the delegate which resides in that same display class, which makes sure the value is updated once you decide to execute your query.

Upvotes: 4

Related Questions