13.07.2015 Views

C# in Depth

C# in Depth

C# in Depth

SHOW MORE
SHOW LESS
  • No tags were found...

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

158 CHAPTER 5 Fast-tracked delegatesHow long would it take you to predict the output from list<strong>in</strong>g 5.14 (even with theannotations)? Frankly it would take me a little while—longer than I like to spendunderstand<strong>in</strong>g code. Just as an exercise, though, let’s look at what happens.First let’s consider the outside variable B. The scope it’s declared <strong>in</strong> is only enteredonce, so it’s a straightforward case—there’s only ever one of it, effectively. The <strong>in</strong>sidevariable C is a different matter—each loop iteration <strong>in</strong>stantiates a new one. Thatmeans that when we create the delegate <strong>in</strong>stance D the outside variable is sharedbetween the two delegate <strong>in</strong>stances, but each of them has its own <strong>in</strong>side variable.After the loop has ended, we call the first delegate <strong>in</strong>stance we created three times.Because it’s <strong>in</strong>crement<strong>in</strong>g both of its captured variables each time, and we started offwith them both as 0, we see (0,0), then (1,1), then (2,2). The difference between thetwo variables <strong>in</strong> terms of scope becomes apparent when we execute the second delegate<strong>in</strong>stance. It has a different <strong>in</strong>side variable, so that still has its <strong>in</strong>itial value of 0,but the outside variable is the one we’ve already <strong>in</strong>cremented three times. The outputfrom call<strong>in</strong>g the second delegate twice is therefore (3,0), then (4,1).NOTE How does this happen <strong>in</strong>ternally? Just for the sake of <strong>in</strong>terest, let’s th<strong>in</strong>kabout how this is implemented—at least with Microsoft’s <strong>C#</strong> 2 compiler.What happens is that one extra class is generated to hold the outer variable,and another one is generated to hold an <strong>in</strong>ner variable and a referenceto the first extra class. Essentially, each scope that conta<strong>in</strong>s a capturedvariable gets its own type, with a reference to the next scope out that conta<strong>in</strong>sa captured variable. In our case, there were two <strong>in</strong>stances of the typehold<strong>in</strong>g <strong>in</strong>ner, and they both refer to the same <strong>in</strong>stance of the type hold<strong>in</strong>gouter. Other implementations may vary, but this is the most obviousway of do<strong>in</strong>g th<strong>in</strong>gs.Even after you understand this code fully, it’s still quite a good template for experiment<strong>in</strong>gwith other elements of captured variables. As we noted earlier, certa<strong>in</strong> elementsof variable capture are implementation specific, and it’s often useful to refer tothe specification to see what’s guaranteed—but it’s also important to be able to justplay with code to see what happens.It’s possible that there are situations where code like list<strong>in</strong>g 5.14 would be the simplestand clearest way of express<strong>in</strong>g the desired behavior—but I’d have to see it to believeit, and I’d certa<strong>in</strong>ly want comments <strong>in</strong> the code to expla<strong>in</strong> what would happen. So, whenis it appropriate to use captured variables, and what do you need to look out for?5.5.7 Captured variable guidel<strong>in</strong>es and summaryHopefully this section has conv<strong>in</strong>ced you to be very careful with captured variables.They make good logical sense (and any change to make them simpler would probablyeither make them less useful or less logical), but they make it quite easy to producehorribly complicated code.Don’t let that discourage you from us<strong>in</strong>g them sensibly, though—they can save youmasses of tedious code, and when they’re used appropriately they can be the mostreadable way of gett<strong>in</strong>g the job done. But what counts as “sensible”?Licensed to Rhona Hadida

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!