Prev | Current Page 305 | Next

Jon Skeet

"C# in Depth: What you need to master C# 2 and 3"

WriteLine(counter);
counter++;
};
7 In case you??™re wondering: return people.Where(person => person.Age < limit);
Listing 5.12 Demonstration of a captured variable having its lifetime extended
155 Capturing variables in anonymous methods
ret();
return ret;
}
...
ThreadStart x = CreateDelegateInstance();
x();
x();
The output of listing 5.12 consists of the numbers 5, 6, and 7 on separate lines. The
first line of output comes from the invocation of the delegate instance within
CreateDelegateInstance, so it makes sense that the value of i is available at that
point. But what about after the method has returned? Normally we would consider
counter to be on the stack, so when the stack frame for CreateDelegateInstance is
destroyed we??™d expect counter to effectively vanish??¦ and yet subsequent invocations
of the returned delegate instance seem to keep using it!
The secret is to challenge the assumption that counter is on the stack in the first
place. It isn??™t. The compiler has actually created an extra class to hold the variable.
The CreateDelegateInstance method has a reference to an instance of that class so it
can use counter, and the delegate has a reference to the same instance??”which lives
on the heap in the normal way. That instance isn??™t eligible for garbage collection until
the delegate is ready to be collected. Some aspects of anonymous methods are very
compiler specific (in other words different compilers could achieve the same semantics
in different ways), but it??™s hard to see how the specified behavior could be
achieved without using an extra class to hold the captured variable.


Pages:
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317