I’m reading manning book about LINQ, and there is an example:
static class QueryReuse
{
static double Square(double n)
{
Console.WriteLine("Computing Square("+n+")...");
return Math.Pow(n, 2);
}
public static void Main()
{
int[] numbers = {1, 2, 3};
var query =
from n in numbers
select Square(n);
foreach (var n in query)
Console.WriteLine(n);
for (int i = 0; i < numbers.Length; i++)
numbers[i] = numbers[i]+10;
Console.WriteLine("- Collection updated -");
foreach (var n in query)
Console.WriteLine(n);
}
}
with the following output:
Computing Square(1)...
1
Computing Square(2)...
4
Computing Square(3)...
9
- Collection updated -
Computing Square(11)...
121
Computing Square(12)...
144
Computing Square(13)...
169
Does this means, that ‘numbers’ is passed by reference? Does this behavior have to do something with lazy execution and yield? Or I’m on a wrong track here?
It’s to do with lazy execution. Every time you iterate through the query, that will be looking at
numbersagain. Indeed, if you change the value of a late element ofnumberswhile you’re executing the query, you’ll see that change too. This is all changing the contents of the array.Note that the query remembers the value of
numbersat the time of the query creation – but that value is a reference, not the contents of the array. So if you change the value ofnumbersitself like this:then that change won’t be reflected in the query.
Just to complicate things, if you use variables within other parts of the query, like this:
then the variable
xis captured rather than its value… so changingxwill change the results of evaluating the query. That’s because the query expression is really translated to:Note that here,
xis used within a lambda expression, butnumbersisn’t – that’s why they behave slightly differently.