<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Yet Another Language Geek : Programming</title><link>http://blogs.msdn.com/wesdyer/archive/tags/Programming/default.aspx</link><description>Tags: Programming</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Musings on Software Testing</title><link>http://blogs.msdn.com/wesdyer/archive/2007/12/07/musings-on-software-testing.aspx</link><pubDate>Fri, 07 Dec 2007 22:42:24 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6696424</guid><dc:creator>wesdyer</dc:creator><slash:comments>15</slash:comments><comments>http://blogs.msdn.com/wesdyer/comments/6696424.aspx</comments><wfw:commentRss>http://blogs.msdn.com/wesdyer/commentrss.aspx?PostID=6696424</wfw:commentRss><description>&lt;p&gt;It was spring 2003, I had just finished a weekend camping in the southern Arizona desert.&amp;#160; I was dusty and physically exhausted from hours of playing paintball.&amp;#160; For those who have never been in those parts, imagine long straight roads with dry sage brush, painful cactus, and jagged mountains.&amp;#160; I needed a book to pass the time during the drive.&amp;#160; Fortunately, I had brought along &lt;a href="http://www.amazon.com/Extreme-Programming-Explained-Embrace-Change/dp/0321278658/ref=pd_bbs_sr_1/104-8800337-6061564?ie=UTF8&amp;amp;s=books&amp;amp;qid=1191966305&amp;amp;sr=8-1"&gt;&amp;quot;Extreme Programming Explained&amp;quot;&lt;/a&gt; by &lt;a href="http://en.wikipedia.org/wiki/Kent_Beck"&gt;Kent Beck&lt;/a&gt;.&amp;#160; After having spent too much time in projects that either completely lacked process or had way too much of it, Beck's position seemed like a revelation.&amp;#160; Over the next few months, I became acquainted with &lt;a href="http://www.amazon.com/Test-Driven-Development-Addison-Wesley-Signature/dp/0321146530/ref=pd_bxgy_b_img_b/104-8800337-6061564"&gt;test-driven development&lt;/a&gt;, &lt;a href="http://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional/dp/0201633612/ref=pd_sim_b_shvl_img_1/104-8800337-6061564"&gt;design patterns&lt;/a&gt;, &lt;a href="http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672/ref=pd_bxgy_b_img_b/104-8800337-6061564"&gt;refactoring&lt;/a&gt; and many of the other topics typically associated with &lt;a href="http://en.wikipedia.org/wiki/Agile_programming"&gt;agile programming&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Test Driven Development&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;In the spring, I had a course that ended up just teaching agile programming concepts.&amp;#160; One of the things that the professor emphasized was following the test-driven development (TDD) process to the letter. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/EscapingtheFixedPointofDevelopment_D551/image_6.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="335" alt="image" src="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/EscapingtheFixedPointofDevelopment_D551/image_thumb_2.png" width="518" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;The TDD Process:&lt;/a&gt;   &lt;blockquote&gt;   &lt;p&gt;1.&amp;#160; Add a test &lt;/p&gt;    &lt;p&gt;2.&amp;#160; Run all tests and see the new one fail &lt;/p&gt;    &lt;p&gt;3.&amp;#160; Write some code &lt;/p&gt;    &lt;p&gt;4.&amp;#160; Run the automated tests and see them succeed&amp;#160; &lt;/p&gt;    &lt;p&gt;5.&amp;#160; &lt;a href="http://en.wikipedia.org/wiki/Refactor"&gt;Refactor&lt;/a&gt; code &lt;/p&gt;    &lt;p&gt;&lt;em&gt;Repeat&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;When I say refactor, I mean it in the strictest sense.&amp;#160; I mean changing how a program is arranged internally without changing the semantics of the program at all.&amp;#160; This of course ignores the fact that things like timing, working set, or stack size change which can be material to the run-time behavior of the program.&lt;/p&gt;  &lt;p&gt;During step three a programmer should remember, &amp;quot;It is important that the code written is &lt;i&gt;only&lt;/i&gt; designed to pass the test; no further (and therefore untested) functionality should be predicted and 'allowed for' at any stage&amp;quot;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Machine Learning&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt; I fully bought into this rigorous approach to TDD until one summer day when I was reading through &lt;a href="http://www.cs.cmu.edu/~tom/"&gt;Tom Mitchell&lt;/a&gt;'s marvelous book &lt;a href="http://www.amazon.com/Machine-Learning-Tom-M-Mitchell/dp/0070428077/ref=sr_1_2/104-8800337-6061564?ie=UTF8&amp;amp;s=books&amp;amp;qid=1191967459&amp;amp;sr=1-2"&gt;&amp;quot;Machine Learning&amp;quot;&lt;/a&gt;.&amp;#160; The book begins by defining &lt;a href="http://en.wikipedia.org/wiki/Machine_learning"&gt;machine learning&lt;/a&gt;: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;A computer program is said to &lt;strong&gt;learn&lt;/strong&gt; from experience &lt;em&gt;E&lt;/em&gt; with respect to some class of tasks &lt;em&gt;T&lt;/em&gt; and performance measure &lt;em&gt;P&lt;/em&gt;, if its performance at tasks in &lt;em&gt;T&lt;/em&gt;, as measured by &lt;em&gt;P&lt;/em&gt;, improves with experience &lt;em&gt;E.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Intuitively, the learning process is trying to learn some unknown concept.&amp;#160; The learner has access to its past experiences (the training data) and uses them to generate a hypothesis of the unknown concept.&amp;#160; This hypothesis is then evaluated and the new experiences are added to the training data.&amp;#160; The learning process then repeats itself as the learner forms a better approximation of the underlying concept.&amp;#160; &lt;/p&gt;  &lt;p&gt;TDD is a learning process.&amp;#160; Where the training experience &lt;em&gt;E&lt;/em&gt; is the automated tests, the task &lt;em&gt;T &lt;/em&gt;is improving the quality of the program, and the performance measure &lt;em&gt;P&lt;/em&gt; is the percentage of tests passed.&amp;#160; In this view of TDD, the programmer continues to hack away at his program generating hypotheses, where each hypothesis is a version of the code, until one satisfies the data.&amp;#160; Note that unless the tests exhaustively specify the desired behavior of a program, then the tests &lt;em&gt;are not&lt;/em&gt; the target concept that needs to be learned but rather a few data points where the target concept is manifest.&amp;#160; Furthermore, the program should not only do well against the tests but also against real world scenarios which may not be covered by the tests. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/EscapingtheFixedPointofDevelopment_D551/j0385807_2.jpg"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="288" alt="j0385807" src="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/EscapingtheFixedPointofDevelopment_D551/j0385807_thumb.jpg" width="404" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Bias and Learning&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;A learner is characterized by its hypothesis space and &lt;a href="http://jmvidal.cse.sc.edu/talks/conceptlearning/learningassearch.xml?style=White"&gt;how it searches through that space&lt;/a&gt;.&amp;#160; Notice that since each learner has a hypothesis space, a given concept may have not be in that space.&amp;#160; One solution to this problem is to make a learner's hypothesis space &lt;a href="http://jmvidal.cse.sc.edu/talks/conceptlearning/unbiasedlearner.xml?style=White"&gt;include all hypotheses&lt;/a&gt;, but this leads to a &lt;a href="http://jmvidal.cse.sc.edu/talks/conceptlearning/futilityofnobias.xml?style=White"&gt;fundamental problem&lt;/a&gt;: &amp;quot;a learner that makes no a priori assumptions regarding the identity of the target concept has no rational basis for classifying any unseen instances.&amp;quot;&amp;#160; The only thing that an unbiased learner can do is regurgitate the training data because it has no ability to make the assumptions and logical leaps necessary to deal with unseen data. &lt;/p&gt;  &lt;p&gt;For example, suppose that I am trying to learn to classify animals as either mammals or non-mammals and suppose that I make no assumptions whatsoever in the process of learning this task.&amp;#160; If I am told that giraffes, lions, mice, bats, and whales are mammals but snakes, butterflies, frogs, lobsters, and&amp;#160; penguins are not, then I only have the ability to answer questions regarding those animals for which I already know the answer.&amp;#160; I could have done much better by trying to guess at what makes an animal a mammal even if I got it wrong! &lt;/p&gt;  &lt;p&gt;Returning to TDD, note that at no time is a programmer supposed to write code that generalizes to the target concept.&amp;#160; The programmer should only write either the minimal code to make a test pass or refactor the code and not change the semantics.&amp;#160; So according to the pure TDD approach, the program would only learn to regurgitate the training data and do who knows what against new examples.&amp;#160; A critic might respond that more test cases are needed.&amp;#160; In some cases where the input space is finite and small, this might well help, but in general this is impractical. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Sufficiently Large Projects&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;A similar situation arises in projects that are sufficiently large.&amp;#160; These projects are characterized by the fact that they cannot be held inside any one person's head.&amp;#160; This means that when someone is making a change, they cannot know all of the consequences of their change.&amp;#160; Often in projects of this size, when people ask if a particular change is good, the response is, &amp;quot;It passed the tests.&amp;quot;&amp;#160; This leads to a state where the development process as a whole is a learning process that uses the test cases as the training data and generates programs as hypotheses that are evaluated against the training data.&amp;#160; Most likely, the target concept is not normally fully determined by the tests. &lt;/p&gt;  &lt;p&gt;You know the projects that I am talking about, and chances are that you have seen some code that was added in just to satisfy some test but didn't really capture the essence of what the test was originally trying to make the program do.&amp;#160; While tests are invaluable to programmers for debugging purposes, it would be better if programmers returned to the specification in order to understand what they are supposed to develop instead of returning to the tests.&lt;/p&gt;  &lt;p&gt;Testing practices like clean-room testing and various forms of white box testing address address the programmer bias deficiency, but it can also be addressed automatically.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Testing an Infinite Space&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;I had a development lead who liked to say that testing is just sampling.&amp;#160; In a sense he is right, since a test is a particular input sequence given to a program from the set of all possible input sequences.&amp;#160; Think of a program as a state machine encoded in your &lt;a href="http://en.wikipedia.org/wiki/Process_calculus"&gt;favorite process calculus&lt;/a&gt;.&amp;#160; A test then verifies that a particular path of edges corresponding to the transitions based on the input ends in a particular state.&amp;#160; Most interesting programs have an infinite number of possible input sequences because of their recursive nature and so the set of tests must be sampled from an infinite input space. &lt;/p&gt;  &lt;p&gt;Testing creates tests by drawing input sequences out of the input sequence space.&amp;#160; It is easy to imagine that tests could be generated randomly by selecting random input sequences.&amp;#160; Random selection has several advantages.&amp;#160; First, it enables statistical measures of quality.&amp;#160; For example, if we sample uniformly then the pass/fail rate should be representative of the whole given a large enough sample.&amp;#160; We could also keep generating more and more tests to improve our confidence that the program is indeed correct.&amp;#160; Second, random tests have the added benefit of not allowing the programmers to just &amp;quot;pass the tests&amp;quot; since the programmers cannot anticipate what tests will be run.&amp;#160; This forces the programmers to generate a hypothesis that more closely matches the target concept instead of the training data. &lt;/p&gt;  &lt;p&gt;There are however some disadvantages.&amp;#160; The first apparent problem is repeatability of the tests.&amp;#160; This can be remedied by storing the seed that generates a set of tests.&amp;#160; A second more serious problem is that a uniform random sample doesn't necessarily deliver the best results. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;On Bugs&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;Not all bugs are created equal.&amp;#160; Practices such as testing the boundary conditions and integration testing are based on that fact.&amp;#160; Various testing practices explore parts of the input space that are richer in bugs or are more likely to contain serious bugs. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/EscapingtheFixedPointofDevelopment_D551/image_8.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="168" alt="image" src="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/EscapingtheFixedPointofDevelopment_D551/image_thumb_3.png" width="628" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The cost of a bug can be quantified as the total monetary loss due to the presence of that bug in the software.&amp;#160; This includes all sorts of things like lost sales through negative customer perception, cost of software patches, legal action, etc.&amp;#160; While this is an accurate measure of cost, it is not very practical because it is very hard to estimate.&lt;/p&gt;  &lt;p&gt;A more practical measure for estimating the relative cost of a bug might be the probability that users will find it multiplied by the severity of the bug.&amp;#160; The first part of the equation is interesting because it indicates that those bugs that customers never find are not important for testing to find. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Back to Training&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The testing ideal is to minimize the total cost of bugs.&amp;#160; There are many good methods for writing test cases.&amp;#160; In addition to these, we could also select input sequences based upon the probability that a user would select such an input sequence.&lt;/p&gt;  &lt;p&gt;Imagine if it were possible to collect all of the input sequences that would ever be given to a program including duplicates.&amp;#160; Then our problem would be reduced to uniformly selecting input sequences out of this collection.&amp;#160; Obviously, this collection is unavailable but if we use the same machine learning principles which we have been discussing then we could develop a program that could learn to generate test cases according to some distribution by using a representative set of user input sequences as training data.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Markov Chains&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;One way that this could be done is by returning to the formulation of a computer program as a state machine.&amp;#160; The object is to learn the probability that a user would take some transition given a particular state and a sequence of previous states and transitions.&amp;#160; This can be formulated as a &lt;a href="http://en.wikipedia.org/wiki/Markov_chain"&gt;Markov chain&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Consider generating random test cases for a parser.&amp;#160; A straightforward approach is to randomly derive a &lt;a href="http://en.wikipedia.org/wiki/String_%28computer_science%29"&gt;string&lt;/a&gt; in the &lt;a href="http://en.wikipedia.org/wiki/Formal_language"&gt;language&lt;/a&gt; from the root &lt;a href="http://en.wikipedia.org/wiki/Nonterminal_symbol"&gt;non-terminal&lt;/a&gt;; however, it will quickly become apparent that the least used parts of your language are getting undue attention.&amp;#160; Some more sophisticated tools allow productions in the &lt;a href="http://en.wikipedia.org/wiki/Formal_grammar"&gt;grammar&lt;/a&gt; to be attributed with weights.&amp;#160; This works better but forces the tester to learn the proper weights manually and it doesn't accurately describe the weights since the probability that a particular &lt;a href="http://en.wikipedia.org/wiki/Production_%28computer_science%29"&gt;production&lt;/a&gt; for a non-terminal will be used is also based on the history of previously expanded productions.&lt;/p&gt;  &lt;p&gt;A better approach is to learn weights for the Markov chain corresponding to the &lt;a href="http://en.wikipedia.org/wiki/Pushdown_automata"&gt;pushdown automata&lt;/a&gt;.&amp;#160; Since a parser for an arbitrary &lt;a href="http://en.wikipedia.org/wiki/Context-free_grammar"&gt;context-free grammar&lt;/a&gt; can be expressed by a pushdown automaton, we can instrument the automaton to collect data on the probability of some transition given a state and a history of states and transitions.&amp;#160; The instrumented automaton can then be fed a large number of user-written programs.&amp;#160; Finally, a generator can be created that uses the data to generate programs that syntactically look like user-written programs.&lt;/p&gt;  &lt;p&gt;Another approach might be to instrument branches and event sequences in a program and then train against user input.&amp;#160; The learner could then build a Markov chain that can be used to generate input sequences roughly like user input.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Next time you find yourself in a project that is devolving into an unbiased learning process, restore the sanity by using the specification and not the tests to decide what to implement. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6696424" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Programming/default.aspx">Programming</category></item><item><title>All About Iterators</title><link>http://blogs.msdn.com/wesdyer/archive/2007/03/23/all-about-iterators.aspx</link><pubDate>Fri, 23 Mar 2007 11:26:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1935848</guid><dc:creator>wesdyer</dc:creator><slash:comments>16</slash:comments><comments>http://blogs.msdn.com/wesdyer/comments/1935848.aspx</comments><wfw:commentRss>http://blogs.msdn.com/wesdyer/commentrss.aspx?PostID=1935848</wfw:commentRss><description>&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Design_pattern_(computer_science)"&gt;Design patterns&lt;/a&gt; have been all of the rage for a number of years now.&amp;nbsp; We have design patterns for concurrency, user interfaces, data access, object creation, and so many other things.&amp;nbsp; The seminal work on the topic is the &lt;a href="http://en.wikipedia.org/wiki/Gang_of_Four_%28software%29"&gt;Gang of Four&lt;/a&gt;'s book, &lt;a href="http://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional/dp/0201633612/ref=pd_bbs_1/002-3886557-6494420?ie=UTF8&amp;amp;s=books&amp;amp;qid=1174622120&amp;amp;sr=8-1"&gt;Design Patterns&lt;/a&gt;.&amp;nbsp; When used appropriately they are a fantastic way to codify the wisdom gleaned from the battles we have fought building software systems.&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.paulgraham.com/icad.html"&gt;One&lt;/a&gt; &lt;a href="http://perl.plover.com/yak/design/"&gt;of&lt;/a&gt; &lt;a href="http://discuss.joelonsoftware.com/default.asp?joel.3.219431.12"&gt;the&lt;/a&gt; &lt;a href="http://norvig.com/design-patterns/ppframe.htm"&gt;criticisms&lt;/a&gt; &lt;a href="http://www.parand.com/say/index.php/2005/07/18/i-hate-patterns/"&gt;leveled&lt;/a&gt; &lt;a href="http://citeseer.ist.psu.edu/felleisen90expressive.html"&gt;at&lt;/a&gt; &lt;a href="http://etymon.blogspot.com/2006/04/perils-of-avoiding-heresy-or-what-are.html"&gt;design&lt;/a&gt; &lt;a href="http://blog.plover.com/prog/design-patterns.html"&gt;patterns&lt;/a&gt; is that they are simply formalisms to address&amp;nbsp;weaknesses in&amp;nbsp;programming languages.&amp;nbsp; They require&amp;nbsp;the human compiler to generate code&amp;nbsp;whenever a&amp;nbsp;specific recurring problem is encountered that cannot be solved directly with language support.&amp;nbsp; Now this might sound like heresy to some, but&amp;nbsp;there is some truth to the criticism.&amp;nbsp; Programmers adapt to the shortcomings in the languages they use by generating pattern like code either by hand or with &lt;a href="http://en.wikipedia.org/wiki/Metaprogramming"&gt;metaprogramming&lt;/a&gt; (generics, dynamic code generation, reflection, expression trees, macros).&lt;/p&gt; &lt;p&gt;Let's take a look at one such example.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;The Iterator Design Pattern&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Among the many patterns&amp;nbsp;in the literature is the &lt;a href="http://en.wikipedia.org/wiki/Iterator_pattern"&gt;iterator pattern&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;img height="275" alt="Iterator Design Pattern" src="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/TheCostofIterators_A895/image015.png" width="420"&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;In .NET this pattern is embodied by &lt;a href="http://msdn2.microsoft.com/en-us/library/system.collections.ienumerable.aspx"&gt;IEnumerable&lt;/a&gt;/&lt;a href="http://msdn2.microsoft.com/en-us/library/9eekhta0.aspx"&gt;IEnumerable&amp;lt;T&amp;gt;&lt;t&gt;&lt;/a&gt; and &lt;a href="http://msdn2.microsoft.com/en-us/library/system.collections.ienumerator.aspx"&gt;IEnumerator&lt;/a&gt;/&lt;a href="http://msdn2.microsoft.com/en-us/library/78dfe2yb.aspx"&gt;IEnumerator&amp;lt;T&amp;gt;&lt;t&gt;&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;img height="78" alt="IEnumerable&amp;lt;T&amp;gt; and IEnumerator&amp;lt;T&amp;gt;" src="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/TheCostofIterators_A895/image014.png" width="425"&gt; &lt;/p&gt; &lt;p&gt;An IEnumerable&amp;lt;T&amp;gt; is something that can be enumerated (iterated) by calling GetEnumerator which will return an IEnumerator&amp;lt;T&amp;gt; (iterator).&amp;nbsp; The IEnumerator&amp;lt;T&amp;gt; is used to move a virtual cursor over the items that are iterated.&lt;/p&gt; &lt;p&gt;Implementing the iterator pattern is a bit onerous.&amp;nbsp; For example, here is the suggested iterator implementation for List&amp;lt;T&amp;gt;&amp;nbsp;from the Design Pattern book.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;class ListIterator&amp;lt;T&amp;gt; : IEnumerator&amp;lt;T&amp;gt;&lt;br&gt;{&lt;br&gt;&amp;nbsp; List&amp;lt;T&amp;gt; list;&lt;br&gt;&amp;nbsp; int current; &lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp; public ListIterator(List&amp;lt;T&amp;gt; list)&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.list = list;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; current = -1;&lt;br&gt;&amp;nbsp; } &lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp; public T Current {&amp;nbsp;get { return list[current]; } } &lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp; public bool MoveNext()&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ++current &amp;lt; list.Count;&lt;br&gt;&amp;nbsp; } &lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp; public void Reset()&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; current = -1;&lt;br&gt;&amp;nbsp; }&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Since we can't change the list itself, we can introduce a ListIterable&amp;lt;T&amp;gt; that wraps a list.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;class ListIterable&amp;lt;T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;&lt;br&gt;{&lt;br&gt;&amp;nbsp; List&amp;lt;T&amp;gt; list; &lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp; public ListIterable(List&amp;lt;T&amp;gt; list)&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.list = list;&lt;br&gt;&amp;nbsp; } &lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp; public IEnumerator&amp;lt;T&amp;gt; GetEnumerator()&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return new ListIterator&amp;lt;T&amp;gt;(list);&lt;br&gt;&amp;nbsp; } &lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;} &lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;And finally, we can write a method called GetElements which returns an IEnumerable&amp;lt;T&amp;gt; over the elements of a List&amp;lt;T&amp;gt;.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;static IEnumerable&amp;lt;T&amp;gt; GetElements&amp;lt;T&amp;gt;(this List&amp;lt;T&amp;gt; list)&lt;br&gt;{&lt;br&gt;&amp;nbsp; return new ListIterable&amp;lt;T&amp;gt;(list);&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&lt;strong&gt;Iterators in C#&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Fortunately in most cases programmers don't need to deal with the iterator design pattern directly since the introduction of iterators in C# 2.0.&amp;nbsp; Instead of writing the iterator above, we can simply write the following:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;static IEnumerable&amp;lt;T&amp;gt; GetElements&amp;lt;T&amp;gt;(this List&amp;lt;T&amp;gt; list)&lt;br&gt;{&lt;br&gt;&amp;nbsp; for (int index = 0; index &amp;lt; list.Count; ++index)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return list[index];&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;When the C# compiler sees this method, it translates it into something very similar to the ListIterator&amp;lt;T&amp;gt; and ListIterable&amp;lt;T&amp;gt;&amp;nbsp;above.&amp;nbsp; Using Reflector or ILDasm we can see that the GetElements method is rewritten as (the names have been changed for clarity as the compiler generates unspeakable names;):  &lt;blockquote&gt;&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;private static IEnumerable&amp;lt;T&amp;gt; GetElements&amp;lt;T&amp;gt;(this List&amp;lt;T&amp;gt; list)&lt;br&gt;{&lt;br&gt;&amp;nbsp; GetElementsIterator&amp;lt;T&amp;gt; temp = new GetElementsIterator&amp;lt;T&amp;gt;(-2);&lt;br&gt;&amp;nbsp; temp.listParameter = list;&lt;br&gt;&amp;nbsp; return temp;&lt;br&gt;}&lt;/font&gt;&lt;pre&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;This is remarkably closer to the first GetElements&amp;nbsp;we wrote rather than the second.&amp;nbsp;&amp;nbsp;Like in the first GetElements, we create an object that implements IEnumerable&amp;lt;T&amp;gt; and parameterize this object with the list that was passed in.&amp;nbsp; The &lt;em&gt;only&lt;/em&gt; other thing that happens in this implementation that doesn't in the first GetElements method&amp;nbsp;is a -2 is passed into the object.&amp;nbsp; I'll come back to this later, but first let's take a look at the GetElementsIterator&amp;lt;T&amp;gt; class (I omitted a few details and changed names&amp;nbsp;for clarity). 
&lt;blockquote&gt;&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;private sealed class GetElementsIterator&amp;lt;T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;, IEnumerator&amp;lt;T&amp;gt;&lt;br&gt;{&lt;br&gt;&amp;nbsp; int state;&lt;br&gt;&amp;nbsp; T current;&lt;br&gt;&amp;nbsp; public List&amp;lt;T&amp;gt; listParameter;&lt;br&gt;&amp;nbsp; int initialThreadId;&lt;br&gt;&amp;nbsp; public int index;&lt;br&gt;&amp;nbsp; public List&amp;lt;T&amp;gt; list; &lt;/font&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp; public GetElementsIterator(int state);&lt;br&gt;&amp;nbsp; private bool MoveNext();&lt;br&gt;&amp;nbsp; IEnumerator&amp;lt;T&amp;gt; IEnumerable&amp;lt;T&amp;gt;.GetEnumerator();&lt;br&gt;&amp;nbsp; void IEnumerator.Reset(); &lt;/font&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp; T IEnumerator&amp;lt;T&amp;gt;.Current { get; }&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The most important thing to note at this time is that GetElementsIterator implements &lt;em&gt;both &lt;/em&gt;IEnumerable&amp;lt;T&amp;gt; and IEnumerator&amp;lt;T&amp;gt;.&amp;nbsp; A strange combination, but we will see why in a little while.&amp;nbsp; Now let's look at what actually happened when we ran the constructor.&amp;nbsp; &lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;public GetElementsIterator(int state)&lt;br&gt;{&lt;br&gt;&amp;nbsp; this.state = state;&lt;br&gt;&amp;nbsp; this.initialThreadId = Thread.CurrentThread.ManagedThreadId;&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Did the constructor run the for loop?&amp;nbsp; No, it didn't.&amp;nbsp; It took some variable called state in and marked what thread created the iterator (if you look at Whidbey code the initialThreadId stuff won't be there...I'll get to that).&amp;nbsp; The state variable marks what state the GetElementsIterator is in.&amp;nbsp; The number -2 is the "I'm an IEnumerable&amp;lt;T&amp;gt;" state.&amp;nbsp; Now, let's look at the GetEnumerator method. 
&lt;blockquote&gt;&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;IEnumerator&amp;lt;T&amp;gt; IEnumerable&amp;lt;T&amp;gt;.GetEnumerator()&lt;br&gt;{&lt;br&gt;&amp;nbsp; GetElementsIterator&amp;lt;T&amp;gt; temp;&lt;br&gt;&amp;nbsp; if ((Thread.CurrentThread.ManagedThreadId == initialThreadId) &amp;amp;&amp;amp; (state == -2))&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; state = 0;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; temp = this;&lt;br&gt;&amp;nbsp; }&lt;br&gt;&amp;nbsp; else&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; temp = new GetElementsIterator&amp;lt;T&amp;gt;(0);&lt;br&gt;&amp;nbsp; }&lt;br&gt;&amp;nbsp; temp.list = this.listParameter;&lt;br&gt;&amp;nbsp; return temp;&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;The method first checks to see if the thread that is calling GetEnumerator is the same thread that created the GetElementsIterator object.&amp;nbsp; If it is the same thread and if the GetElementsIterator is in the "I'm an IEnumerable&amp;lt;T&amp;gt;" state then the state is changed to the "I'm an initialized IEnumerator&amp;lt;T&amp;gt;" state.&amp;nbsp; Otherwise, a new object of the same type is created but it is immediately put in the "I'm an initialized IEnumerator&amp;lt;T&amp;gt;" state so that thread safety is maintained.&amp;nbsp; Finally, in either case the list that was passed from the GetElements method is copied into the list field for consumption by the MoveNext method. 
&lt;p&gt;In Whidbey code, you will see that the if statement is different because an Interlock.Exchange was used to perform the same task.&amp;nbsp; The change was made to improve performance (especially for iterators that have 0 or 1 items to iterate over). 
&lt;p&gt;Now we have seen why GetElementsIterator implements both IEnumerable&amp;lt;T&amp;gt; and IEnumerator&amp;lt;T&amp;gt;, because it can morph from the IEnumerable&amp;lt;T&amp;gt; role into the IEnumerator&amp;lt;T&amp;gt; role without creating any new objects in most cases. 
&lt;p&gt;The Current property is very simple. 
&lt;blockquote&gt;&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;T IEnumerator&amp;lt;T&amp;gt;.Current&lt;br&gt;{&lt;br&gt;&amp;nbsp; get&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return current;&lt;br&gt;&amp;nbsp; }&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;The Reset method simply throws a NotSupportedException. 
&lt;p&gt;This leaves us with only the MoveNext to examine.&amp;nbsp; We still haven't seen where the for loop went.&amp;nbsp; Hopefully, it is in the MoveNext.&amp;nbsp; The following code is produced with the /o+ compiler option (optimizations turned on). 
&lt;blockquote&gt;&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;private bool MoveNext()&lt;br&gt;{&lt;br&gt;&amp;nbsp; switch (state)&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp; case 0:&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; state = -1;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; index = 0;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; break; &lt;/font&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp; case 1:&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; state = -1;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; index++;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; break; &lt;/font&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp; default:&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto Done;&lt;br&gt;&amp;nbsp; }&lt;br&gt;&amp;nbsp; if (index &amp;lt; list.Count)&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; current = list[index];&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; state = 1;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return true;&lt;br&gt;&amp;nbsp; }&lt;br&gt;Done:&lt;br&gt;&amp;nbsp; return false;&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;Hm...a switch statement over a variable called state with a number integer case labels.&amp;nbsp; It looks like a state machine and indeed it is.&amp;nbsp; When MoveNext is first called, state is equal to 0, so the state is set to -1 (the "I'm finished" state) and the index is set to 0.&amp;nbsp; Then we check to see if the index is less than the number of things in the list.&amp;nbsp; If so then we set current to the current list element based on the index and set the state to 1.&amp;nbsp; We return true indicating that there is something to consume. 
&lt;p&gt;The second call to MoveNext will run case 1 since the state is equal to 1.&amp;nbsp; It will again set the state to -1 and increment the index.&amp;nbsp; If we still have elements in the list then the current will be set appropriately and the state will be set to 1 (the "we need to check again" state) and true will be returned. 
&lt;p&gt;This continues until there nothing left to consume and false is returned. 
&lt;p&gt;Finally, we found our for loop.&amp;nbsp; It is encoded in the MoveNext.&amp;nbsp; But note that on each call to MoveNext is only computes the part of the for loop that is relevant to realize the next element.&amp;nbsp; It never computes more than it needs to.&amp;nbsp; This is why iterators are an example of deferred execution.&amp;nbsp; When the actual GetElements method was called, no elements were realized at all!&amp;nbsp; Later as MoveNext is called, one element at a time is realized.&amp;nbsp; This of course enables all of sorts of &lt;a href="http://blogs.msdn.com/wesdyer/archive/2007/02/13/the-virtues-of-laziness.aspx"&gt;great scenarios&lt;/a&gt; such as the pay-as-you-go model and the ability to have infinite lists. 
&lt;p&gt;&lt;strong&gt;The Cost of Iterators&lt;/strong&gt; 
&lt;p&gt;Iterators are very performant.&amp;nbsp; In almost all situations that I have encountered they are more than performant enough and they simplify the code drastically as we have seen.&amp;nbsp; But sometimes you can get into trouble. 
&lt;p&gt;Consider the definition of the Concat sequence operator in Linq to Objects.&amp;nbsp; It looks something like this: 
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;static IEnumerable&amp;lt;T&amp;gt; Concat&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; sequence1, IEnumerable&amp;lt;T&amp;gt; sequence2)&lt;br&gt;{&lt;br&gt;&amp;nbsp; foreach (var item in sequence1)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return item;&lt;br&gt;&amp;nbsp; foreach (var item in sequence2)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return item;&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Let's write a little benchmark to evaluate the performance of concat. 
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;var stopWatch = new Stopwatch();&lt;br&gt;for (int length = 0; length &amp;lt;= 10000; length += 1000)&lt;br&gt;{&lt;br&gt;&amp;nbsp; var list = new[] { 1 };&lt;br&gt;&amp;nbsp; IEnumerable&amp;lt;int&amp;gt; ones = list;&lt;br&gt;&amp;nbsp; for (int i = 0; i &amp;lt; length; ++i)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ones = ones.Concat(list); &lt;/font&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp; stopWatch.Reset();&lt;br&gt;&amp;nbsp; stopWatch.Start(); &lt;/font&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp; foreach (var item in ones) ; &lt;/font&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp; stopWatch.Stop();&lt;br&gt;&amp;nbsp; Console.WriteLine("Length: {0} Time: {1}", length, stopWatch.ElapsedMilliseconds);&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The results may be perhaps surprising.&amp;nbsp; The time to evalute the foreach statement is not linearly proportional to the number of concats that are composed together.&amp;nbsp; In fact it is proportional to the square of the number of concats composed together.&lt;/p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/TheCostofIterators_A895/image022.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="307" src="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/TheCostofIterators_A895/image0_thumb14.png" width="520" border="0"&gt;&lt;/a&gt; 
&lt;p&gt;Upon closer inspection the reason why is obvious.&amp;nbsp; The time complexity of Concat is O(m+n) where m is the number of items in the first sequence and n is the number of items in the second sequence.&amp;nbsp; But note that in this example, n is always 1.&amp;nbsp; The outermost call is O(m+1).&amp;nbsp; The next call has O((m-1)+1), then O((m-2)+1), ... O(1+1).&amp;nbsp; There are m of these calls so the running time should be O(m^2).&amp;nbsp; Essentially, composing concats together like this causes O(m^2) yield returns to be executed. 
&lt;p&gt;Of course, using a List&amp;lt;T&amp;gt; here and adding on the sequences would have been much more performant because it eliminates the redundant calculations but it would not have been evaluated lazily. 
&lt;p&gt;Iterators are even more fun if the data structure that is being enumerated is more complicated.&amp;nbsp; For example, consider iterating over n-ary trees.&amp;nbsp; Here is a quick definition of a n-ary tree. 
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;class Tree&amp;lt;T&amp;gt;&lt;br&gt;{&lt;br&gt;&amp;nbsp; public T Value { get; private set; }&lt;br&gt;&amp;nbsp; public Tree&amp;lt;T&amp;gt; NextSibling { get; private set; }&lt;br&gt;&amp;nbsp; public Tree&amp;lt;T&amp;gt; FirstChild { get; private set; } &lt;/font&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp; public Tree(T value, Tree&amp;lt;T&amp;gt; nextSibling, Tree&amp;lt;T&amp;gt; firstChild)&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Value = value;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NextSibling = nextSibling;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FirstChild = firstChild;&lt;br&gt;&amp;nbsp; } &lt;/font&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp; public IEnumerable&amp;lt;Tree&amp;lt;T&amp;gt;&amp;gt; GetChildren()&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (var current = FirstChild; current != null; current = current.NextSibling)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return current;&lt;br&gt;&amp;nbsp; }&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Now it is easy to define an iterator that performs a preorder traversal of a n-ary tree. 
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;static IEnumerable&amp;lt;T&amp;gt; PreOrderWalk&amp;lt;T&amp;gt;(this Tree&amp;lt;T&amp;gt; tree)&lt;br&gt;{&lt;br&gt;&amp;nbsp; if (tree == null)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield break;&lt;br&gt;&amp;nbsp; yield return tree.Value;&lt;br&gt;&amp;nbsp; foreach (var subTree in tree.GetChildren())&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (var item in subTree.PreOrderWalk())&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return item;&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Just the way that I like code: clear and concise.&amp;nbsp; The only problem is that the iterator could be more efficient.&amp;nbsp; This may or may not be a problem.&amp;nbsp; In a library it will almost certainly be a problem. 
&lt;p&gt;We can improve the efficiency somewhat by changing the code: 
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;static IEnumerable&amp;lt;T&amp;gt; PreOrderWalk&amp;lt;T&amp;gt;(this Tree&amp;lt;T&amp;gt; tree)&lt;br&gt;{&lt;br&gt;&amp;nbsp; var stack = new Stack&amp;lt;Tree&amp;lt;T&amp;gt;&amp;gt;();&lt;br&gt;&amp;nbsp; if (tree != null)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; stack.Push(tree);&lt;br&gt;&amp;nbsp; while (stack.Count &amp;gt; 0)&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (var current = stack.Pop(); current != null; current = current.FirstChild)&lt;br&gt;&amp;nbsp; &amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; yield return current.Value;&lt;br&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (current.NextSibling != null)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; stack.Push(current.NextSibling);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp; }&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;This second iterator doesn't recursively call iterators thus&amp;nbsp;avoiding both the recursive call and the extra allocations.&amp;nbsp; Instead, it maintains a stack of work to do after the leftmost path has been exhausted.&amp;nbsp; Once the leftmost path has been exhausted then a node is popped off and the leftmost traversal is resumed at that node. 
&lt;p&gt;When we measure the difference, we see that the improvement is noticeable but that the number of nodes, O(b^d) where b is the branching factor and d is depth,&amp;nbsp;dominates the cost of the traversal.&amp;nbsp; In the graph below, the green line indicates the total number of nodes in the tree.&amp;nbsp; The trees have a branching factor of 2. 
&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/TheCostofIterators_A895/image026.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="310" src="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/TheCostofIterators_A895/image0_thumb16.png" width="517" border="0"&gt;&lt;/a&gt; 
&lt;p&gt;So the key takeaway here is that iterators have great performance but as always &lt;em&gt;measure the performance of your code&lt;/em&gt;.&amp;nbsp; If you find that performance is suffering, use a combination of profiling and analysis to find the problem.&amp;nbsp; If the problem is an iterator, you might be able to increase the performance by reworking the iterator as in the n-ary tree case.&amp;nbsp; In other cases, it might be the usage of the iterators as&amp;nbsp;with pathological Concats. 
&lt;p&gt;&lt;strong&gt;One Possibility for Language Improvement (not in Orcas)&lt;/strong&gt; 
&lt;p&gt;The Concat sequence operator is interesting because there is a lot of code that is seemingly redundant.&amp;nbsp; It takes two sequences and then has to iterate over them and yield their elements.&amp;nbsp; It's like it needs to expand their insides just to package them up together again.&amp;nbsp; As we have seen this doesn't lead to the best performance and the code is overly verbose. 
&lt;p&gt;Bart Jacobs, Erik Meijer, Frank Piessens, and Wolfram Shulte wrote &lt;a href="http://citeseer.ist.psu.edu/cache/papers/cs2/355/http:zSzzSzwww.cs.kuleuven.ac.bezSz~frankzSzPAPERSzSzFTfJP2005.pdf/iterators-revisited-proof-rules.pdf"&gt;a very interesting paper&lt;/a&gt; on a possible language improvement that would improve both the usability and the performance of iterators.&amp;nbsp; The second half of the paper details what they call nested iterators which avoid the multiple evaluation problem of the composed Concats and implicitly keep an internal stack like the modified n-ary tree iterator. 
&lt;p&gt;For example with this language feature, the Concat sequence operator would look something like this: 
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;static IEnumerable&amp;lt;T&amp;gt; Concat&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; sequence1, IEnumerable&amp;lt;T&amp;gt; sequence2)&lt;br&gt;{&lt;br&gt;&amp;nbsp; yield foreach sequence1;&lt;br&gt;&amp;nbsp; yield foreach sequence2;&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Notice that the code is simplier and it is also more performant. 
&lt;p&gt;A&amp;nbsp;programmer could use yield return, yield break, and yield foreach in the same iterator.&amp;nbsp; An iterator FromTo can be defined recursively as follows: 
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;static IEnumerable&amp;lt;int&amp;gt; FromTo(int b, int e)&lt;br&gt;{&lt;br&gt;&amp;nbsp; if (b &amp;gt; e)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield break;&lt;br&gt;&amp;nbsp; yield return b;&lt;br&gt;&amp;nbsp; yield foreach FromTo(b + 1, e);&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;If instead of the yield foreach, there was the foreach expansion that yielded each result then the FromTo method would suffer from quadratic performance; however, with nested iterators the performance would be linear. 
&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/TheCostofIterators_A895/image031.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="368" src="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/TheCostofIterators_A895/image0_thumb19.png" width="558" border="0"&gt;&lt;/a&gt; 
&lt;p&gt;The next post will pick up on understanding the performance of Linq to objects queries. 
&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1935848" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Design+Patterns/default.aspx">Design Patterns</category></item><item><title>Performance Engineering</title><link>http://blogs.msdn.com/wesdyer/archive/2007/03/20/performance-engineering.aspx</link><pubDate>Tue, 20 Mar 2007 12:52:56 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1918500</guid><dc:creator>wesdyer</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/wesdyer/comments/1918500.aspx</comments><wfw:commentRss>http://blogs.msdn.com/wesdyer/commentrss.aspx?PostID=1918500</wfw:commentRss><description>&lt;p&gt;Recently, many people have asked me about the performance of Linq.&amp;nbsp; The questions have ranged from the broad, "How can I analyze the performance of code using Linq?", to the very specific, "Why is the performance of this code sample not what I expected?"&lt;/p&gt; &lt;p&gt;I want to address these questions.&amp;nbsp;&amp;nbsp;So before I dive into some of them individually, I want to set up a framework for discussions about performance.&amp;nbsp; The framework consists of ideas that are well known and understood and yet often when people talk or think about performance they forget about them.&lt;/p&gt; &lt;p&gt;Performance&amp;nbsp;is&amp;nbsp;critical to the success of any application and &lt;em&gt;engineering&lt;/em&gt; performance is a fundamental part of what developers should be doing on a day to day basis.&amp;nbsp; Great performance doesn't just happen.&amp;nbsp; It must have requirements, be designed, implemented, and tested just like any other feature.&amp;nbsp; Individuals and teams must foster a culture of performance.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Performance Requirements&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Rico Mariani wrote a great post about why performance must be &lt;a href="http://blogs.msdn.com/ricom/archive/2006/12/21/do-performance-analysis-in-context.aspx"&gt;measured in context&lt;/a&gt;.&amp;nbsp; That means that performance goals should be made in relation to what the user sees and cares about.&amp;nbsp; Then when possible these goals should be translated into more low-level goals that are easier to quantify and directly measure, but never take your eye of the original goals.&amp;nbsp; Many times when performance is tuned in one dimension it can degrade in other dimensions.&amp;nbsp; It is like trying to cram a whole bunch of stuff into a tiny space, you may push it in here but it pops out over there.&amp;nbsp; So how does a programmer know which dimension is most important?&amp;nbsp; Consider the performance in context.&amp;nbsp; Furthermore, the performance tuning that a programmer makes might not even matter when considered in context.&amp;nbsp; So spend your time where in counts.&amp;nbsp;&amp;nbsp;Finally, it is much easier to consider trade-offs between performance requirements and other requirements when the performance requirements are in context.&amp;nbsp; Set up a performance budget in terms that are material and important&amp;nbsp;to the customer.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Designing for Performance&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Designing for performance is important.&amp;nbsp; Many performance problems can be fixed as they are identified later, but some are deeply rooted in poor design choices that were made early on that are difficult to resolve later.&amp;nbsp; However, care must be taken because often these poor design choices were made for the sake of "better performance".&amp;nbsp; For example, in an app where there is a lot of data parallelism, it doesn't make a lot of sense to make it so complex with stateful&amp;nbsp;operations that it precludes concurrency.&lt;/p&gt; &lt;p&gt;Most of these poor design choices are caused by the design not solving the right problem (performance requirements)&amp;nbsp;or because the requirements changed over time and the earlier design made it difficult to adapt to the new requirements.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Understanding Performance&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;There are at least two basic tools for understanding performance.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;1.&amp;nbsp; &lt;/strong&gt;&lt;a href="http://en.wikipedia.org/wiki/Asymptotic_analysis"&gt;&lt;strong&gt;Asymptotic Analysis&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I am sure that my readers know and love asymptotic analysis.&amp;nbsp; It is so important that developers know what they are doing when they call a System.* function, which&amp;nbsp;has an O(n) time complexity, n times -- O(n^2) behavior.&amp;nbsp; Know what is going on in terms of both space and time.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;2.&amp;nbsp; Benchmarks / Profilers&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;So often when a performance problem exists, developers will convince themselves that they know what the problem is&amp;nbsp;without accurately measuring the behavior of the system.&amp;nbsp; They will proceed to "fix" the problem only to discover that what they thought would be of great benefit is in fact unimportant.&lt;/p&gt; &lt;p&gt;I've done that.&amp;nbsp; When C# 1.0 was in beta back in 2000, I was working at a small company that decided to try out this new .NET stuff.&amp;nbsp; My first application was a&amp;nbsp;good sized&amp;nbsp;application that including a custom scripting engine inside of it.&amp;nbsp; The performance wasn't great and so I set about fixing it.&amp;nbsp; I was sure that I knew what the problem was and so I began improving some algorithms in various complex parts of the system.&amp;nbsp; But I found that it didn't help matters at all.&lt;/p&gt; &lt;p&gt;At this point, I broke out a profiler and began measuring the actual behavior of the system.&amp;nbsp; The suprising result (at the time) was that pretty much all of the performance problems came from a small loop that was building up the text buffer for the scripting engine.&amp;nbsp; It was using the + operator on strings.&amp;nbsp; Since this was my first .NET application, I had no idea that concatenating hundreds of thousands of strings was a bad idea.&lt;/p&gt; &lt;p&gt;When I changed the code to use a StringBuilder instead, it sailed.&amp;nbsp; I made a few other improvements (all of which were targeted and very small), and the application was running fine.&lt;/p&gt; &lt;p&gt;Now the point of all of this is &lt;em&gt;not&lt;/em&gt; that the + operator on strings should not be used.&amp;nbsp; If that were true then we would make the C# compiler issue a warning when you used it.&amp;nbsp; The point is that a programmer should be aware of the costs and tradeoffs involved with a programming decision and act accordingly.&amp;nbsp; Measurement is a powerful tool.&amp;nbsp; Knowing where the problems lie is&amp;nbsp;the key to success.&amp;nbsp; Measure early and often.&lt;/p&gt; &lt;p&gt;The result of profiling is a large set of various statistics about an application.&amp;nbsp; If the measurements are taken in context then they are a powerful tool.&amp;nbsp; As with any statistics, what is being measured is as important as the actual measurement.&lt;/p&gt; &lt;p&gt;Analyzing an application is very rewarding.&amp;nbsp; You are able to see the material benefits of any improvement in a very quantitative way.&amp;nbsp; Apply the scientific method in the process of analyzing a problem.&amp;nbsp; Once you suspect you know what the problem is then consider it the hypothesis and then prove it by observing the data (profiling data)&amp;nbsp;from an operation (the suspect code) across various trials.&lt;/p&gt; &lt;p&gt;Try to think big and understand not only what is the problem but why it is a problem.&amp;nbsp; The best solutions attack not only the symptoms but the fundamental causes of the problem.&amp;nbsp; Look to understand the nature of the problem.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Some Good Performance Resources&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/ricom/"&gt;Rico Mariani's (Visual Studio&amp;nbsp;Performance Architect) Blog&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/vancem/"&gt;Vance Morrison's (CLR Performance Architect) Blog&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1918500" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Programming/default.aspx">Programming</category></item><item><title>Linq to ASCII Art</title><link>http://blogs.msdn.com/wesdyer/archive/2007/02/23/linq-to-ascii-art.aspx</link><pubDate>Fri, 23 Feb 2007 09:02:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1745602</guid><dc:creator>wesdyer</dc:creator><slash:comments>40</slash:comments><comments>http://blogs.msdn.com/wesdyer/comments/1745602.aspx</comments><wfw:commentRss>http://blogs.msdn.com/wesdyer/commentrss.aspx?PostID=1745602</wfw:commentRss><description>&lt;p&gt;Last night I was searching for an audio version of &lt;em&gt;&lt;a href="http://www.amazon.com/Hackers-Painters-Big-Ideas-Computer/dp/0596006624"&gt;Painters and Hackers&lt;/a&gt;&lt;/em&gt; by &lt;a href="http://www.paulgraham.com/"&gt;Paul Graham&lt;/a&gt;.&amp;nbsp; Pretty soon I had completely forgotten about the book and found myself reading the &lt;a href="http://en.wikipedia.org/wiki/Main_Page"&gt;Wikipedia&lt;/a&gt; article about &lt;a href="http://en.wikipedia.org/wiki/Hacker"&gt;Hackers&lt;/a&gt;.&amp;nbsp; Isn't Internet search great?&lt;/p&gt; &lt;p&gt;Of all of the things in the article, the one thing that captured my attention was the &lt;a href="http://en.wikipedia.org/wiki/Image:Lamoascii.png"&gt;ASCII picture&lt;/a&gt; of &lt;a href="http://en.wikipedia.org/wiki/Adrian_Lamo"&gt;Adrian Lamo&lt;/a&gt;.&amp;nbsp; I immediately thought, "How cool is that!?"&amp;nbsp; So instead of&amp;nbsp;popping off my current stack frame and returning to searching for &lt;em&gt;Painters and Hackers&lt;/em&gt;, I began thinking about how to create such a picture.&amp;nbsp; I certainly did not want to create it by hand.&amp;nbsp; I didn't even want to pick which characters or colors would be printed to the screen.&amp;nbsp; So accordingly, I began thinking of writing a program to do it for me.&lt;/p&gt; &lt;p&gt;I grabbed the latest bits and began writing code.&amp;nbsp; A few hours later, I had a working program with a few bells and whistles too.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;ASCII Art&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Here is an example of converting &lt;a href="http://en.wikipedia.org/wiki/Gandalf"&gt;Gandalf&lt;/a&gt; from pixels to &lt;a href="http://www.asciitable.com/"&gt;ASCII&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/LinqtoASCIIArt_12D96/image036.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="424" src="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/LinqtoASCIIArt_12D96/image0_thumb28.png" width="334" border="0"&gt;&lt;/a&gt;&lt;a href="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/LinqtoASCIIArt_12D96/image%7B0%7D%5B3%5D.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="424" src="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/LinqtoASCIIArt_12D96/image%7B0%7D_thumb%5B1%5D.png" width="350" border="0"&gt; &lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;How to Convert and Image to ASCII Art&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The process works like this:&lt;/p&gt; &lt;p&gt;Determine how big of an area will be used for displaying the ASCII art.&amp;nbsp; By default, the width of the image will be the width of the console's buffer and the height will be computed so as the preserve the ratio of width to height from the original image.&lt;/p&gt; &lt;p&gt;Now divide the original image into as many rectangles as will be used to display the ASCII.&amp;nbsp; For each rectangle in the original picture determine its grayscale value by averaging the&amp;nbsp;grayscale values&amp;nbsp;of each pixel.&amp;nbsp; The grayscale value of a pixel is:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;GrayScale = .3 * Red + .59 * Green + .11 * Blue&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;We then increase the contrast of each region by some amount (d is the luminosity of a region, contrast is any double but usually around 1.5):&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;public static double Contrast(this double d, double contrast)&lt;br&gt;{&lt;br&gt;&amp;nbsp; return (((d - .5) * contrast) + .5).Bound(0, 1);&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Finally, for each region in the ASCII art we choose from an array of possible ASCII figures (sorted) by the grayscale value for that region.&amp;nbsp; The ASCII figure with the closest luminosity is picked.&lt;/p&gt; &lt;p&gt;The only point that I haven't covered is how the array of ASCII figures was generated.&amp;nbsp; I could have done this by hand if I wanted to, but I didn't want to.&amp;nbsp; Instead, I generate the grayscale figures each time.&amp;nbsp; Each figure consists of a character and a console color either ConsoleColor.DarkGray, ConsoleColor.Gray, or ConsoleColor.White.&amp;nbsp; The characters are one of the alphanumeric characters or&amp;nbsp;the special symbols (things like %, $, @, ...).&amp;nbsp; The program generates all of the combinations and then measures their grayscale value by drawing them to a hidden bitmap and then computing their average grayscale value.&amp;nbsp; The figures are sorted by this value and a final grayscale is built.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;A Few&amp;nbsp;Snippets&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you take a look at the source, you will notice that it is written rather different than most C# code.&amp;nbsp; A lot of the code resides in extension methods and there are a number of lambdas and queries.&amp;nbsp; In fact, loops are kind of rare in the code.&amp;nbsp; For example, here is a function that returns all of the pixels in a rectangular region of a bitmap.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;public static IEnumerable&amp;lt;Color&amp;gt; GetPixels(this Bitmap image, Rectangle rect)&lt;br&gt;{&lt;br&gt;&amp;nbsp; return from y in rect.Top.To(rect.Bottom)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; from x in rect.Left.To(rect.Right)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select image.GetPixel(x, y);&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The To function is a helpful little function that I wrote.  &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;public static IEnumerable&amp;lt;int&amp;gt; To(this int start, int end)&lt;br&gt;{&lt;br&gt;&amp;nbsp; var diff = end - start &amp;gt; 0 ? 1 : -1;&lt;br&gt;&amp;nbsp; for (var current = start; current != end; current += diff)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return current;&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Of course, I also could have written Iterate and then written To in terms of that.  &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;public static IEnumerable&amp;lt;T&amp;gt; Iterate&amp;lt;T&amp;gt;(T initialValue, Func&amp;lt;T, bool&amp;gt; predicate, Func&amp;lt;T, T&amp;gt; next)&lt;br&gt;{&lt;br&gt;&amp;nbsp; for (var current = initialValue; predicate(current); current = next(current))&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return current;&lt;br&gt;}&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;public static IEnumerable&amp;lt;int&amp;gt; To(this int start, int end)&lt;br&gt;{&lt;br&gt;&amp;nbsp; var diff = end - start &amp;gt; 0 ? 1 : -1;&lt;br&gt;&amp;nbsp; return Iterate(start, x =&amp;gt; x != end, x =&amp;gt; x + diff);&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Another interesting part is setting up the display and then restoring the original display properties of the console.  &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;using (SetupConsole())&lt;/font&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp; ...&lt;/font&gt; &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Where SetupConsole is defined as:  &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;static ActionDisposable SetupConsole()&lt;br&gt;{&lt;br&gt;&amp;nbsp; var originalBackgroundColor = Console.BackgroundColor;&lt;br&gt;&amp;nbsp; var originalForegroundColor = Console.ForegroundColor;&lt;br&gt;&amp;nbsp; return new ActionDisposable(() =&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.BackgroundColor = originalBackgroundColor;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.ForegroundColor = originalForegroundColor;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Notice that the original state of the console is captured only in the SetupConsole method and does not clutter the rest of the code.&amp;nbsp; The&amp;nbsp;closure&amp;nbsp;that is&amp;nbsp;created contains all of the necessary information to restore the console to its original state.&amp;nbsp; This way we hide data &lt;em&gt;even from private members of the same class&lt;/em&gt;.&amp;nbsp; If they don't need to know, then they don't need to know.&amp;nbsp; Instead only a means for restoring the original state is provided.  &lt;p&gt;I'm sure that the program can be improved a lot.&amp;nbsp; So if you have any comments, suggestions, or bugs then just post a comment.&amp;nbsp; Enjoy!  &lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt;  &lt;p&gt;I took the comments as well as some of my own ideas and improved the ASCII art generator.&amp;nbsp; I also modified the &lt;em&gt;How to Convert an Image to ASCII Art &lt;/em&gt;section to reflect some changes.&amp;nbsp; Thank you to everyone that contributed.  &lt;p&gt;&lt;strong&gt;Download the Source&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.box.net/public/10oy0aodrk"&gt;&lt;img height="24" alt="File icon" src="http://www.box.net/thumbs/24x24/default_file.gif" width="24" align="absMiddle" border="0"&gt;AsciiPictureSource.zip&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.box.net/public/8ofyrvmzho"&gt;&lt;img height="24" alt="File icon" src="http://www.box.net/thumbs/24x24/default_file.gif" width="24" align="absMiddle" border="0"&gt;AsciiPictureSourcev1.1.zip&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1745602" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>How Linq to Objects Queries Work</title><link>http://blogs.msdn.com/wesdyer/archive/2007/01/03/how-linq-to-objects-queries-work.aspx</link><pubDate>Wed, 03 Jan 2007 04:40:26 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1401205</guid><dc:creator>wesdyer</dc:creator><slash:comments>12</slash:comments><comments>http://blogs.msdn.com/wesdyer/comments/1401205.aspx</comments><wfw:commentRss>http://blogs.msdn.com/wesdyer/commentrss.aspx?PostID=1401205</wfw:commentRss><description>&lt;p&gt;If you have ever tried to step through a Linq to Objects query in the debugger, you may have been mildly surprised at the results.&amp;nbsp; It may have seemed as if the program had a mind of its own and ran certain expressions when it wanted to and not when it was supposed to.&amp;nbsp; Be assured, it is doing the right thing and&amp;nbsp;the order of evaluation is giving you a glimpse&amp;nbsp;of what actually happens when a query is evaluated.&lt;/p&gt; &lt;p&gt;Consider this query:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;using System;&lt;br&gt;using System.Linq; &lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;class Program&lt;br&gt;{&lt;br&gt;&amp;nbsp; static void Main()&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var foo = new[] { 4, 2, 1, 3, 0 }; &lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var q = from x in foo&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let square = x * x&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;where square &amp;gt; x&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select new { x, square }; &lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (var item in q) Console.WriteLine(item);&lt;br&gt;&amp;nbsp; }&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Now consider where breakpoints can be set within this program:  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/DebuggingQueries_14149/image06.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="381" src="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/DebuggingQueries_14149/image0_thumb4.png" width="640" border="0"&gt;&lt;/a&gt;  &lt;p&gt;&lt;strong&gt;Pop Quiz&lt;/strong&gt;&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Which order are the breakpoint spans visited in.&amp;nbsp; Try to guess the order of evaluation.&amp;nbsp; Of course you can verify the order in a debugger.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The order may of evaluation may surprise you.&amp;nbsp; Why does it behave like this?&amp;nbsp; Well, to really understand we need to translate it.&amp;nbsp; First, lets translate the query:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;var q = foo.Select(x =&amp;gt; new { x, square = x * x })&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .Where(t0 =&amp;gt; t0.square &amp;gt; t0.x)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .Select(t0 =&amp;gt; new { t0.x, t0.square });&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Now, lets change the extension methods to static method calls.  &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;var q = Enumerable.Select(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Enumerable.Where(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Enumerable.Select(foo, x =&amp;gt; new { x, square = x * x }),&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t0 =&amp;gt; t0.square &amp;gt; t0.x),&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t0 =&amp;gt; new { t0.x, t0.square });&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Now, lets look at how Enumerable.Select and Enumerable.Where are implemented.&amp;nbsp; We can not include the "using System.Linq" and instead implement Select, Where, and Func ourselves.  &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;using System;&lt;br&gt;using System.Collections.Generic; &lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;delegate R Func&amp;lt;A,R&amp;gt;(A arg0); &lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;static class Program&lt;br&gt;{&lt;br&gt;&amp;nbsp; static void Main()&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var foo = new [] { 4, 2, 1, 3, 0 }; &lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var q = Select(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Where(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Select(foo, x =&amp;gt; new { x, square = x * x }),&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;t0 =&amp;gt; t0.square &amp;gt; t0.x),&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;t0 =&amp;gt; new { t0.x, t0.square }); &lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (var item in q) Console.WriteLine(item);&lt;br&gt;&amp;nbsp; } &lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp; static IEnumerable&amp;lt;U&amp;gt; Select&amp;lt;T,U&amp;gt;(IEnumerable&amp;lt;T&amp;gt; sequence, Func&amp;lt;T, U&amp;gt; selector)&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (var item in sequence)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return selector(item);&lt;br&gt;&amp;nbsp; } &lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp; static IEnumerable&amp;lt;T&amp;gt; Where&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; sequence, Func&amp;lt;T, bool&amp;gt; predicate)&lt;br&gt;&amp;nbsp;&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (var item in sequence)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (predicate(item))&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return item;&lt;br&gt;&amp;nbsp; }&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Now consider what happens when we run this program which is essentially identical to our original program.&amp;nbsp; First, foo is assigned a reference to an array of ints.&amp;nbsp; Next since C# uses pass-by-value parameter passing by default, the arguments to the methods must be &lt;em&gt;evaluated&lt;/em&gt; before the functions can be &lt;em&gt;applied&lt;/em&gt; to their arguments.&amp;nbsp; So the innermost Select call is called first which creates a Select Iterator using foo as the source but note that it &lt;em&gt;does not run the iterator.&amp;nbsp; &lt;/em&gt;This behavior is called &lt;a href="http://en.wikipedia.org/wiki/Lazy_evaluation"&gt;lazy evaluation&lt;/a&gt;.&amp;nbsp; In some other world, in perhaps a different language, the iterator could immediately evaluate all of its results, cache them, and then return them when demanded; but, this is not what happens with iterators in C#.&amp;nbsp; When you call a method that is an iterator, the iterator is only constructed but not run.&amp;nbsp; Remember that the iterator object that was constructed implements IEnumerable and so in this case it can be used as the first parameter to the Where method.&amp;nbsp; Finally, the result of the Where method is passed to the final Select method.&amp;nbsp; The whole result is assigned to q.&amp;nbsp; Note, that q is &lt;em&gt;not actually a realized result set&lt;/em&gt;.&amp;nbsp; In fact, q is object that &lt;em&gt;can compute the result set when required&lt;/em&gt;.&amp;nbsp; Since, q is made up of iterators it will only do the minimum work necessary to return the next element when asked.&lt;/p&gt; &lt;p&gt;So in the foreach statement when the first element of q is requested,&amp;nbsp;the outermost Select iterator begins running but it requires its source to return the first element which in turn runs the Where iterator which needs its source which in turn calls the innermost Select iterator which requires its source to be realized but that source is foo which simply returns 4 as the first element.&amp;nbsp; The innermost Select iterator then produces a tuple of x and the square of x and returns this result.&amp;nbsp; The Where iterator then checks the predicate against this first element and it passes so it returns the result.&amp;nbsp; The outermost Select iterator then produces a projection using this result.&amp;nbsp; &lt;em&gt;Note that the minimum possible work was done to compute the first result of the query&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;This works precisely as before for the second query result but when we ask for the third result things start to get a bit more interesting.&amp;nbsp; Again the outermost Select iterator calls the Where iterator which calls the innermost&amp;nbsp;Select iterator which asks foo for its next element which is 1.&amp;nbsp; The innermost Select iterator makes a tuple with 1 and its square.&amp;nbsp; The Where iterator then checks the condition and it fails so it does not return the item but requests the innermost Select iterator to produce another result which is does and this second result then passes the Where predicate.&amp;nbsp; The outermost Select iterator then gets 3 and its square which are projected and returned as the third result of q.&amp;nbsp; It is easy to see that queries essentially become a pipeline where each computation is fed to the next and all are independent of the others &lt;a href="http://blogs.msdn.com/wesdyer/archive/2006/12/26/a-model-for-query-interpretation.aspx"&gt;as has been previously described&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;There are several important implications based on how Linq to Objects queries actually work.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;1.&amp;nbsp; Laziness enables the ability to work with infinite sequences&lt;/p&gt; &lt;p&gt;2.&amp;nbsp; Operations which require the entire source to be examined change the order of evaluation&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&lt;strong&gt;1.&amp;nbsp; Laziness and the Infinite&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Here is a program which displays the first 10 positive odd numbers.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;using System;&lt;br&gt;using System.Collections.Generic;&lt;br&gt;using System.Linq; &lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;static class Program&lt;br&gt;{&lt;br&gt;&amp;nbsp; static void Main()&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var odds = from x in NaturalNumbers()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select 2 * x + 1; &lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (var item in odds.Take(10)) Console.WriteLine(item);&lt;br&gt;&amp;nbsp; } &lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp; static IEnumerable&amp;lt;int&amp;gt; NaturalNumbers()&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (var n = 0; ; n++)&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return n;&lt;br&gt;&amp;nbsp; }&lt;br&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Notice that the NaturalNumbers iterator never ends (Yes, it would overflow but lets ignore that for the sake of this discussion).&amp;nbsp; The query then says for each natural number project twice the number and add one which is the definition of odd.&amp;nbsp; If this query immediately evaluated the results then this program would not terminate since NaturalNumbers never terminates; however, the program does terminate.&amp;nbsp; When query is created, it only constructs the information necessary to evaluate the query later.&amp;nbsp; Then when we foreach over the query, the query returns one result at a time as they are required.&amp;nbsp; In fact, in this case we also add another computation step onto q in the foreach statement by saying that we will only &lt;em&gt;take&lt;/em&gt; the first 10 results so only the first ten natural numbers were even created.&amp;nbsp; This is beautiful.&amp;nbsp; Lazy evaluation enables the ability to work with the infinite.&amp;nbsp; I will have a lot more to say about this topic another time.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;2.&amp;nbsp; Forced Evaluation&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;There are some operations that require whole source examination before a single result can be passed on to the next operation.&amp;nbsp; One such operation is orderby.&amp;nbsp; In order to determine the position of any element, the whole sequence must be examined.&amp;nbsp; Thus, if we add an orderby to our original query then the order of evaluation of the query will dramatically change.&lt;/p&gt;&lt;font face="Courier New"&gt; &lt;blockquote&gt; &lt;p&gt;var q = from x in foo&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; let square = x * x&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; where square &amp;gt; x&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; orderby x&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select new { x, square };&lt;/p&gt;&lt;/blockquote&gt;&lt;/font&gt; &lt;p&gt;If you run the query in the debugger now, you will notice that the let, where, and orderby operations are all performed before the first select operation is performed.&amp;nbsp; Subsequent elements will skip the let, where, and orderby and go straight to the select statement.&amp;nbsp; This is because the orderby operation forced the evaluation of all of the previous operations.&amp;nbsp; Subsequent results do not need to evaluate the let, where, or orderby operations because they have already been evaluated.&lt;/p&gt; &lt;p&gt;Other common operations that cause this behavior are join, join...into, and group...by clauses.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Corollary to (1) and (2) - Forced Evaluation and the Infinite&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Now consider what would happen if we tried to use orderby with NaturalNumbers.&amp;nbsp; As you might expect, our program would never terminate.&amp;nbsp; To use the two together we would need to make sure that we only use a section of NaturalNumbers like NaturalNumbers.Take(10).&amp;nbsp; This is because even though queries are lazy, if operations are used which force the evaluation of all of the results then the benefits of being lazy are effectively removed.&amp;nbsp; So&amp;nbsp;we must be careful&amp;nbsp;when using infinite sequences.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1401205" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Queries/default.aspx">Queries</category></item><item><title>Reading and Writing Queries</title><link>http://blogs.msdn.com/wesdyer/archive/2006/12/26/reading-and-writing-queries.aspx</link><pubDate>Tue, 26 Dec 2006 05:01:22 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1363656</guid><dc:creator>wesdyer</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/wesdyer/comments/1363656.aspx</comments><wfw:commentRss>http://blogs.msdn.com/wesdyer/commentrss.aspx?PostID=1363656</wfw:commentRss><description>&lt;p&gt;Now that we have discussed some of the underpinnings of query expressions, we can turn our attention to how to use them.&amp;nbsp;&lt;a href="http://blogs.msdn.com/wesdyer/archive/2006/12/21/comprehending-comprehensions.aspx"&gt;As has already discussed&lt;/a&gt;, most people who see query expressions immediately think of SQL and often even mistake query expressions for embedded SQL.&amp;nbsp; While it is true that there is a similarity in the syntax, it has already been pointed out that they are fundamentally different in important ways.&amp;nbsp; Because of their semantic difference and syntactic similarity they seem to cause somewhat of a &lt;a href="http://en.wikipedia.org/wiki/Cognitive_dissonance"&gt;cognitive dissonance&lt;/a&gt; with respect to SQL.&amp;nbsp; In other words, people see query expressions and assume that they behave exactly like SQL.&amp;nbsp; With some providers (LINQ to SQL) this may be largely true, but with others they are very different (LINQ to objects).&amp;nbsp; In this post, we will examine the &lt;a href="http://en.wikipedia.org/wiki/Syntax"&gt;syntax&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Scope_%28programming%29"&gt;scoping rules&lt;/a&gt; of query expressions.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Query Syntax&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;First, let's turn our attention to the matter of syntax.&amp;nbsp; A query is simply a sequence of clauses.&amp;nbsp; There are only&amp;nbsp;nine types of clauses:&amp;nbsp; from, join, join...into, let, where, orderby, group...by, select, into.&amp;nbsp; A query must begin with a from clause and end with either a select or a group by clause.&amp;nbsp; In between the start and the end there may be any number of from, join, join...into, let, where, and orderby clauses.&amp;nbsp; After a query has been ended it may be "continued" by using an into clause followed by any number of from, join, join...into, let, where, and orderby clauses and then followed by either a select or group...by clause.&amp;nbsp; Here is a description of the syntactic structure of each clause (modified &lt;a href="http://en.wikipedia.org/wiki/Ebnf"&gt;EBNF&lt;/a&gt; where more descriptive labels are given to the expression and identifier&amp;nbsp;non-terminals).&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;fromClause -&amp;gt;&amp;nbsp;from&amp;nbsp;&lt;em&gt;variable&lt;/em&gt; in &lt;em&gt;source&lt;/em&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;joinClause -&amp;gt;&amp;nbsp;join&amp;nbsp;&lt;em&gt;variable &lt;/em&gt;in &lt;em&gt;source &lt;/em&gt;on &lt;em&gt;outerKey &lt;/em&gt;equals &lt;em&gt;innerKey&lt;/em&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;joinIntoClause -&amp;gt;&amp;nbsp;join&amp;nbsp;&lt;em&gt;variable&lt;/em&gt; in &lt;em&gt;source &lt;/em&gt;on &lt;em&gt;outerKey &lt;/em&gt;equals &lt;em&gt;innerKey &lt;/em&gt;into &lt;em&gt;groupingVariable&lt;/em&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;letClause -&amp;gt;&amp;nbsp;let &lt;em&gt;variable = expression&lt;/em&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;whereClause -&amp;gt; where &lt;em&gt;condition&lt;/em&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;orderbyClause -&amp;gt;&amp;nbsp;orderby &lt;em&gt;key &lt;/em&gt;[ascending | descending] {, &lt;em&gt;key&lt;/em&gt; [ascending | descending ]}&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;selectClause -&amp;gt; select &lt;em&gt;projection&lt;/em&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;groupByExpression -&amp;gt; group &lt;em&gt;groupingResult &lt;/em&gt;by &lt;em&gt;groupKey&lt;/em&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;intoClause -&amp;gt; into &lt;em&gt;variable&lt;/em&gt;&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Here is an example:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;from c in customers&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;where c.State == "WA"&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;orderby c.Name&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;join o in orders on c.ID equals o.CustomerID&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;let OrderTotal = o.Price * o.Quantity&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;select new { c.Name, OrderTotal }&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Unlike SQL, C# queries do not begin with a select clause.&amp;nbsp; The primary motivation for having the from clause come first is because in C# variables are always declared before they are used.&amp;nbsp; So when c is used in the where clause, it is obvious that this c was introduced before it (in the from clause).&amp;nbsp; One benefit of having a strongly typed language that declares variables before they are used is that IDEs can provide intellisense for these variables when they are used.&amp;nbsp; Other reasons for the differing order of clauses will be discussed in the next post.&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/ScopingoutQueries_1410E/image01.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" src="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/ScopingoutQueries_1410E/image0.png" width="240" border="0"&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Scoping Out Queries&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Based on the syntax and translation rules of query expressions and those of transparent identifiers, it is possible to derive the scoping rules for queries.&amp;nbsp; Mostly these scoping rules are somewhat intuitive, but there are a few places where you might not get what you expect.&amp;nbsp; To discuss the scoping of rules effectively, it is helpful to introduce a few formalisms.&amp;nbsp; We can think of each query clause as a function that takes a scope as input and produces a scope as output.&amp;nbsp; So for example, if &lt;em&gt;s &lt;/em&gt;represents the set of variables that were introduced in this query's previous clauses and are still in scope and &lt;em&gt;o&lt;/em&gt; represents the set of variables that are in scope from outside of the query then after the from clause all the variables in &lt;em&gt;s&amp;nbsp;&lt;/em&gt;and &lt;em&gt;o&lt;/em&gt;&amp;nbsp;are in scope as well as the variable that the from clause introduced.&amp;nbsp; Also, in the source expression in the from clause both the variables from o and from &lt;em&gt;s&lt;/em&gt; are in scope but &lt;em&gt;x&lt;/em&gt; is not in scope.&amp;nbsp; We will denote this as:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;[o,s] -&amp;gt; from x in&amp;nbsp;[o,s]&amp;nbsp;-&amp;gt; [o,s,x]&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;First we see in this notation that variables in &lt;em&gt;o&lt;/em&gt; and &lt;em&gt;s&lt;/em&gt; flow into the query.&amp;nbsp; Then we see that in the source expression in the from clause, all of the variables in &lt;em&gt;o&lt;/em&gt; and &lt;em&gt;s&lt;/em&gt;&amp;nbsp;are in scope.&amp;nbsp; Finally, the notation indicates that after the from clause all of the variables in &lt;em&gt;o&lt;/em&gt; and &lt;em&gt;s&lt;/em&gt; as well as the variable &lt;em&gt;x&lt;/em&gt; are in scope.&amp;nbsp; The following are the scoping rules for each clause (based on the rewrite rules).&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;[o,s] -&amp;gt; from x in [o,s] -&amp;gt; [o,s,x]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;[o,s] -&amp;gt; join x in [o] on [o,s] equals [o,x] -&amp;gt; [o,s,x]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;[o,s] -&amp;gt; join x in [o] on [o,s] equals [o,x] into g -&amp;gt; [o,s,g]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;[o,s] -&amp;gt; let x = [o,s] -&amp;gt; [o,s,x]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;[o,s] -&amp;gt; where [o,s] -&amp;gt; [o,s]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;[o,s] -&amp;gt; orderby [o,s] -&amp;gt; [o,s]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;[o,s] -&amp;gt; group [o,s] by [o,s] -&amp;gt; [o,s]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;[o,s] -&amp;gt; select [o,s] -&amp;gt; [o,s]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;[o,s] -&amp;gt; into x -&amp;gt; [o,x]&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Again, the spec does not call out these scoping rules.&amp;nbsp; They are an emergent behavior given the rewrite rules and the rules for transparent identifiers.&lt;/p&gt; &lt;p&gt;Occasionally, I talk to someone who wonders why the two key expressions in a join clause are not commutable.&amp;nbsp;&amp;nbsp;One reason becomes apparent after examining the scoping rules: the expressions are not commutable because they don't have the same variables in scope.&amp;nbsp; The join query variable is not in scope in the outer key expression while the previous query variables are not in scope in the inner key expression.&lt;/p&gt; &lt;p&gt;Using these scoping rules we can understand now which variables are in scope in each expression in a query.&amp;nbsp; Try this query out.&amp;nbsp; See if you can figure out which variables are in scope at each point (the answer is at the end of this post).&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;var src = ...;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;var q = from x in [???]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; where [???]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; from y in [???]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; join z in [???] on [???] equals [???] into g&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; orderby [???]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; let a = [???]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select [???]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; into b&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; join c in [???] on [???] equals [???]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; group [???] by [???];&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&lt;strong&gt;Thinking About Query Continuations&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;In the previous section you may have noticed that query continuations (into &lt;em&gt;variable&lt;/em&gt;&amp;nbsp;...) erase all of the variables that were in scope in the query.&amp;nbsp; This is because query continuations take the result of a query and pipe it in to the next query.&amp;nbsp; Looking at the translation rules, we see that a query like:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;from x in foo&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;select f(x)&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;into y&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;select f(y)&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Becomes:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;from y in from x in foo&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;select f(x)&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;select f(y)&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The key here&amp;nbsp;is that we can divide a query into a series of sections where each section ends in either a select or a group by.&amp;nbsp; Each section can be considered independently.&amp;nbsp; For example, instead of thinking of the query as the rewrite indicates, we could think of it as:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;var q1 = from x in foo&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select f(x);&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;var q2 = from y in q1&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;select f(y);&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Notice how each section of the query becomes one query and then is used as the source for the next query section.&amp;nbsp; The difference between this "rewrite" and the specified rewrite is that the specified rewrite produces a single expression while this "rewrite" produces several statements.&amp;nbsp; So while this is not the actual translation, it is helpful in understanding how query continuations work.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Answer to Scoping Question&lt;/strong&gt;&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;var src = ...;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;var q = from x in [src]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;where [src, x]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;from y in [src, x]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; join z in [src] on [src,x,y] equals [src,z] into g&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; orderby [src,x,y,g]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; let a = [src,x,y,g]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select [src,x,y,g,a]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; into b&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; join c in [src] on [src,b] equals [src,c]&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; group [src,b,c] by [src,b,c];&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1363656" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Queries/default.aspx">Queries</category></item><item><title>Thus Quoth the Humble Programmer</title><link>http://blogs.msdn.com/wesdyer/archive/2006/12/22/thus-quoth-the-humble-programmer.aspx</link><pubDate>Sat, 23 Dec 2006 02:20:01 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1349791</guid><dc:creator>wesdyer</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/wesdyer/comments/1349791.aspx</comments><wfw:commentRss>http://blogs.msdn.com/wesdyer/commentrss.aspx?PostID=1349791</wfw:commentRss><description>&lt;p&gt;I love Scheme!&amp;nbsp; It is such a beautiful language.&amp;nbsp; I was first introduced to it during college.&amp;nbsp; At that time, I thought it was an interesting language but I didn't see the power of the language until later.&amp;nbsp; That moment came when I experienced reading &lt;a href="http://mitpress.mit.edu/sicp/full-text/book/book.html"&gt;The Structure and Interpretation of Computer Programs&lt;/a&gt;.&amp;nbsp; It was a great joy to read the text and work through the exercises.&amp;nbsp; But the most fulfilling part was thinking about what it all meant.&amp;nbsp; I definitely encourage anyone who wants to expand their mind to read this wonderful text.&lt;/p&gt; &lt;p&gt;&lt;a onclick="return amz_js_PopWin('http://www.amazon.com/gp/product/images/0262011530/ref=dp_image_0/002-7913622-5508035?ie=UTF8&amp;amp;n=283155&amp;amp;s=books','AmazonHelp','width=700,height=600,resizable=1,scrollbars=1,toolbar=0,status=1');" href="http://www.amazon.com/gp/product/images/0262011530/ref=dp_image_0/002-7913622-5508035?ie=UTF8&amp;amp;n=283155&amp;amp;s=books" target="AmazonHelp"&gt;&lt;img id="prodImage" height="240" alt="Structure and Interpretation of Computer Programs - 2nd Edition (MIT Electrical Engineering and Computer Science)" src="http://ec1.images-amazon.com/images/P/0262011530.01._AA240_SCLZZZZZZZ_.jpg" width="240" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Quoting in Scheme&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Scheme&amp;nbsp;(or any other LISP dialect)&amp;nbsp;allows programmers&amp;nbsp;to&amp;nbsp;define variables, define lambdas, and evaluate expressions (I know that I am greatly simplifying here).&amp;nbsp; But one feature that is particularly interesting is the ability to quote.&amp;nbsp; Quoting an expression causes the expression not be evaluated but instead to return the structure of the expression.&amp;nbsp; For example (line numbers added for discussion purposes):&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;1:&amp;nbsp;&amp;nbsp;&amp;nbsp; (define f1 (lambda (x y) (+ x y)))&lt;br&gt;2:&amp;nbsp;&amp;nbsp;&amp;nbsp; f1&lt;br&gt;3:&amp;nbsp;&amp;nbsp;&amp;nbsp; (define e (quote (lambda (x y) (+ x y))))&lt;br&gt;4:&amp;nbsp;&amp;nbsp;&amp;nbsp; e&lt;br&gt;5:&amp;nbsp;&amp;nbsp;&amp;nbsp; (define f2 (eval e))&lt;br&gt;6:&amp;nbsp;&amp;nbsp;&amp;nbsp; (f1 3 4)&lt;br&gt;7:&amp;nbsp;&amp;nbsp;&amp;nbsp; (f2 3 4)&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;This program produces the following results. &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;#&amp;lt;procedure:f1&amp;gt;&lt;br&gt;(lambda (x y) (+ x y))&lt;br&gt;7&lt;br&gt;7&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Line number 1 defines a variable f1 to be the result of evaluating a lambda expression, thus f1 is a function.&amp;nbsp; Line 2 evaluates f1 which simply returns the function.&amp;nbsp; Line 3 defines e to be the result of evaluating the quote of the same lambda expression that appeared in line 1.&amp;nbsp; But now e is &lt;em&gt;not &lt;/em&gt;a function but rather a structure describing the lambda.&amp;nbsp; Line 4 evaluates e, which displays the structure it references.&amp;nbsp; Line 5 defines a variable f2 to be the result of apply eval to e.&amp;nbsp; Eval runs the Scheme interpreter on its arguments.&amp;nbsp; Recall, that e is a structure describing a lambda.&amp;nbsp; So applying eval to e we get a lambda and so f2 is now a function described by this lambda.&amp;nbsp; Finally, on lines 6 and 7 we apply f1 and f2 respectively to arguments 3 and 4.&amp;nbsp; Since they are both functions that correspond to the same lambda structure we expect to get the same results and indeed we do. &lt;p&gt;&lt;strong&gt;Quoting in C#&lt;/strong&gt; &lt;p&gt;With C# 3.0 we can do essentially the same thing (again line numbers added for discussion purposes). &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;1:&amp;nbsp;&amp;nbsp;&amp;nbsp; Func&amp;lt;int, int, int&amp;gt; f1 = (x, y) =&amp;gt; x + y;&lt;br&gt;2:&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(f1);&lt;br&gt;3:&amp;nbsp;&amp;nbsp;&amp;nbsp; Expression&amp;lt;Func&amp;lt;int, int, int&amp;gt;&amp;gt; e = (x, y) =&amp;gt; x + y;&lt;br&gt;4:&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(e);&lt;br&gt;5:&amp;nbsp;&amp;nbsp;&amp;nbsp; Func&amp;lt;int, int, int&amp;gt; f2 = e.Compile();&lt;br&gt;6:&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(f1(3, 4));&lt;br&gt;7:&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(f2(3, 4));&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;This program displays the following: &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;System.Linq.Func`3[System.Int32,System.Int32,System.Int32]&lt;br&gt;(x, y) =&amp;gt; (x + y)&lt;br&gt;7&lt;br&gt;7&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Notice how remarkably similar both the programs and that outputs are.&amp;nbsp; Again, on line 1 we define a delegate to be the result of evaluating a lambda expression.&amp;nbsp; On line 2, we display this delegate.&amp;nbsp; On line 3, we assign e the result of evaluating a lambda expression.&amp;nbsp; Notice that in C# both assignments (lines&amp;nbsp;1 and 3)&amp;nbsp;look the same except for the type of the variable to which the lambda is assigned.&amp;nbsp; Lambdas can be converted either to delegates or to expression trees depending on the usage.&amp;nbsp; Delegates can be invoked while expression trees preserve the structure of the lambda.&amp;nbsp; On line 4, we display the expression tree for e which corresponds to the structure of the lambda.&amp;nbsp; On line 5, we do the equivalent of the eval in Scheme by compiling the expression tree structure to a delegate.&amp;nbsp; We can now invoke f2 like we can invoke f1.&amp;nbsp; On lines 6 and 7, we invoke these two delegates and display their results. &lt;p&gt;&lt;strong&gt;So What?&lt;/strong&gt; &lt;p&gt;While this is all very remarkable, it may seem a bit esoteric.&amp;nbsp; Why take the trouble to have a variable with a value that corresponds to the structure of a lambda and then convert that to an invocable form?&amp;nbsp; Why not just always create the delegate immediately?&amp;nbsp; The reason is with the expression tree form of the lambda, we can reason about the structure and then take action on it.&amp;nbsp; Consider queries.&amp;nbsp; When a query is translated it creates a number of lambdas, but one of the key questions is: Are those lambdas then converted to delegates or expression trees?&amp;nbsp; For example: &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;var q = from x in foo&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;where x &amp;gt; 1&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;select x + 1;&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;This is &lt;a href="http://blogs.msdn.com/wesdyer/archive/2006/12/21/comprehending-comprehensions.aspx"&gt;translated&lt;/a&gt; to: &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;var q = foo.Where(x =&amp;gt; x &amp;gt; 1)&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .Select(x =&amp;gt; x + 1);&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/wesdyer/archive/2006/12/21/comprehending-comprehensions.aspx"&gt;We have already discussed&lt;/a&gt; that which "Where" and "Select" methods are called depends upon what the type of foo is and which extension methods are in scope.&amp;nbsp; If the "Where" and "Select" methods take a delegate then the lambdas will be converted to delegates; however, if they take an expression tree then the lambdas are converted to expression trees instead.&amp;nbsp; So a LINQ provider (or someone who has implemented the query pattern methods like "Where" and "Select") can choose whether they would like the lambdas in delegate or expression tree form.&amp;nbsp; Now lets look at a few providers and see what they do.&amp;nbsp; LINQ to objects (or the in-memory query operators that apply to IEnumerable&amp;lt;T&amp;gt;) take delegates.&amp;nbsp; This is because they will invoke the delegates to do things like evaluate predicates or projections.&amp;nbsp; However, LINQ to SQL&amp;nbsp;on the other hand takes expression trees.&amp;nbsp; It does not "invoke" the lambdas but instead reasons over the structure of the lambdas and then translates the expression trees to equivalent SQL code given a schema for a database.&amp;nbsp; This is the beauty of the LINQ pattern. &lt;p&gt;Adding the ability to quote lambdas enables all sorts of possiblities.&amp;nbsp; You might easily imagine other uses for expression trees: remoting evaluation of expressions, query planning, executing them on a GPU, .... &lt;p&gt;What can you think of doing?&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1349791" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Queries/default.aspx">Queries</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Scheme/default.aspx">Scheme</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Functional+Programming/default.aspx">Functional Programming</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Lambdas/default.aspx">Lambdas</category></item><item><title>Transparent Identifiers</title><link>http://blogs.msdn.com/wesdyer/archive/2006/12/22/transparent-identifiers.aspx</link><pubDate>Fri, 22 Dec 2006 22:53:41 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1349374</guid><dc:creator>wesdyer</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/wesdyer/comments/1349374.aspx</comments><wfw:commentRss>http://blogs.msdn.com/wesdyer/commentrss.aspx?PostID=1349374</wfw:commentRss><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/wesdyer/archive/2006/12/21/comprehending-comprehensions.aspx"&gt;My last post&lt;/a&gt; described in detail how query expressions in C# are translated, but I have a confession to make.&amp;nbsp; I did a little bit of &lt;a href="http://en.wikipedia.org/wiki/Hand_waving"&gt;hand waving&lt;/a&gt; through one part of the translation rules.&amp;nbsp; The astute reader (whomever that is, whenever I read such things I always wonder, "Am I that astute reader?") may have noticed that four of the rules introduced a decidedly foreign language feature into rewrite rules.&amp;nbsp; For example, examine rule #14 closely:&lt;/p&gt; &lt;p&gt;14.&amp;nbsp; &lt;em&gt;From followed by let&lt;/em&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;from x1 in e1 let x2 = e2 ...&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New"&gt;from * in e1.Select(x1 =&amp;gt; new { x1, x2 = e2 }) ...&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;What is that asterisk in the resultant transformation and what does it mean?&amp;nbsp; It isn't a pointer deferencing operator&amp;nbsp;and it isn't a multiplication operator, hmmm...What could it be?&amp;nbsp; It looks like it is taking the place of an identifier in the from clause but that is a strange name for an identifier.&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/TransparentIdentifiers_CE3F/image%7B0%7D%5B1%5D.png" atomicselection="true"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="222" src="http://blogs.msdn.com/blogfiles/wesdyer/WindowsLiveWriter/TransparentIdentifiers_CE3F/image%7B0%7D.png" width="240" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;In fact, the asterisk denotes a &lt;em&gt;transparent identifier &lt;/em&gt;and it is the name of this identifier.&amp;nbsp;&amp;nbsp;Transparent identifiers&amp;nbsp;are one of the strangest additions to C# 3.0.&amp;nbsp; The spec has precious little to say about them.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;1.&amp;nbsp; They are introduced to a program only by query rewriting&lt;/p&gt; &lt;p&gt;2.&amp;nbsp; Each transparent identifier has exactly one associated anonymous type (the anonymous type introduced during the same rewrite step as the transparent identifier)&lt;/p&gt; &lt;p&gt;3.&amp;nbsp; When a transparent identifier is in scope, its members are in scope as well (transivitely)&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Rule 3 is kind of strange because it mentions &lt;em&gt;scope&lt;/em&gt; in an otherwise syntactic rewrite.&amp;nbsp; &lt;em&gt;Scope&lt;/em&gt; has to do with semantics and not syntax so we have to be very careful how we apply this rule.&amp;nbsp; Now consider the following query:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;from x in foo&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;let y = f(x)&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;let z = g(x, y)&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;select h(x, y, z)&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Applying rule 14 the first time the query is reduced to:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;from * in foo.Select(x =&amp;gt; new { x, y = f(x) })&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;let z = g(x, y)&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;select h(x, y, z)&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Here we introduced a transparent identifier and the anonymous type that is associated with it is new { x, y = f(x) }.&amp;nbsp; Now we apply rule 14 again.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;from * in foo.Select(x =&amp;gt; new { x, y = f(x) }).Select(* =&amp;gt; new { *, z = g(x, y) })&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;select h(x, y, z)&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;We have now introduced another transparent identifier but this one is associated with a different anonymous type.&amp;nbsp; It is associated with new { *, z = g(x, y) }.&amp;nbsp; In order to note the difference they will labeled them *1 and *2.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;from *2 in foo.Select(x =&amp;gt; new { x, y = f(x) }).Select(*1 =&amp;gt; new { *1, z = g(x, y) })&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;select h(x, y, z)&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Finally, we can apply rule 15.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;foo.Select(x =&amp;gt; new { x, y = f(x) }).Select(*1 =&amp;gt; new { *1, z = g(x, y) }).Select(*2 =&amp;gt; h(x, y, z))&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Where *1 and *2 are associated with the following anonymous types:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;*1 = new { x, y = f(x) }&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New"&gt;*2 = new { *1, z = g(x, y) }&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;You may notice that in the final select call that there is a lambda with only one parameter (*2) but in the body of this lambda we reference x, y, and z but none of these variables are in scope.&amp;nbsp; Using rule 3 about transparent identifiers we see that when *2 is in scope so&amp;nbsp;are *1 and z but since *1 is now in scope so are x and y (the transitive closure of the members of *2).&amp;nbsp; So really when we refer to x in h(x, y, z) we are really referring to *2.*1.x.&amp;nbsp; Thus we have the following:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;foo.Select(x =&amp;gt; new { x, y = f(x) }).Select(*1 =&amp;gt; new { *1, z = g(*1.x, *1.y) }).Select(*2 =&amp;gt; h(*2.*1.x, *2.*1.y, *2.z))&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Finally, once we realize that the compiler treats these transparent identifiers just as unspeakable compiler generated names then we see that all the magic has been removed:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New"&gt;foo.Select(x =&amp;gt; new { x, y = f(x) }).Select(t0 =&amp;gt; new { t0, z = g(t0.x, t0.y) }).Select(t1 =&amp;gt; h(t1.t0.x, t1.t0.y, t1.z))&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Voila!&amp;nbsp; No more transparent identifiers.&amp;nbsp; Transparent identifiers are used in query rewriting to package up the intermediate results and pass them onto the next clause.&amp;nbsp; They are&amp;nbsp;means of essentially creating a little scope and passing it around.&amp;nbsp; It is a fantastic idea that allows variables to flow through the queries providing the kind of behavior that users expect to see.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1349374" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Queries/default.aspx">Queries</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Compilers/default.aspx">Compilers</category></item><item><title>Comprehending Comprehensions</title><link>http://blogs.msdn.com/wesdyer/archive/2006/12/21/comprehending-comprehensions.aspx</link><pubDate>Fri, 22 Dec 2006 01:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1342764</guid><dc:creator>wesdyer</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/wesdyer/comments/1342764.aspx</comments><wfw:commentRss>http://blogs.msdn.com/wesdyer/commentrss.aspx?PostID=1342764</wfw:commentRss><description>&lt;P&gt;Not long ago, I was reading through some articles posted on &lt;A href="http://programming.reddit.com/" mce_href="http://programming.reddit.com/"&gt;programming.reddit.com&lt;/A&gt; when I came across an article claiming that &lt;A href="http://blogs.msdn.com/wesdyer/archive/2006/12/20/types-of-confusion.aspx" mce_href="http://blogs.msdn.com/wesdyer/archive/2006/12/20/types-of-confusion.aspx"&gt;C# is trying to be a dynamic language&lt;/A&gt;.&amp;nbsp; One user posted a comment that mentioned that C# 3.0 included among other things "embedded SQL".&amp;nbsp; Unfortunately, it seems that there is still some confusion about what query expressions are.&amp;nbsp; Let's be clear: query expressions are &lt;STRONG&gt;&lt;EM&gt;not&lt;/EM&gt;&lt;/STRONG&gt; embedded SQL.&amp;nbsp; In fact, they are closer to &lt;A href="http://en.wikipedia.org/wiki/List_comprehension" mce_href="http://en.wikipedia.org/wiki/List_comprehension"&gt;list comprehensions&lt;/A&gt; in languages like &lt;A href="http://www.haskell.org/" mce_href="http://www.haskell.org/"&gt;Haskell&lt;/A&gt; and &lt;A href="http://www.python.org/" mce_href="http://www.python.org"&gt;Python&lt;/A&gt; than they are to embedded SQL.&lt;/P&gt;
&lt;P&gt;At a high level, query expressions provide nine basic operations (from, join, join...into, group...by, orderby, where, let, select, into).&amp;nbsp; Each of these basic operations is expressed as a clause.&amp;nbsp; The clauses are then chained together to provide a declaration of query; however, if you only view a query then you can't be sure what the behavior at runtime will be.&amp;nbsp; The reason is that queries are translated into a series of method calls but the methods that are invoked are not predefined methods from the compiler's point of view.&amp;nbsp; The compiler just creates the calls and binds the calls to whatever methods are applicable given the arguments and the receiver of the call.&amp;nbsp; This is both the source of the beauty and the confusion of query expressions.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Syntactic Sugar&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;Query expressions are an interesting language feature because they are &lt;A href="http://en.wikipedia.org/wiki/Syntactic_sugar" mce_href="http://en.wikipedia.org/wiki/Syntactic_sugar"&gt;pure syntactic sugar&lt;/A&gt;.&amp;nbsp; But to really understand queries we need to see what lies beneath.&amp;nbsp; Let's break through the syntactic sugar.&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.geomedien.geographie.uni-kiel.de/referenz/lehre/ss2003/geomulti/Weltmarkt/bilder/sugar_cube_shot.jpg" mce_src="http://www.geomedien.geographie.uni-kiel.de/referenz/lehre/ss2003/geomulti/Weltmarkt/bilder/sugar_cube_shot.jpg"&gt;&lt;/P&gt;
&lt;P&gt;Consider the following query:&lt;/P&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;var&lt;/SPAN&gt; q = &lt;SPAN class=kwrd&gt;from&lt;/SPAN&gt; x &lt;SPAN class=kwrd&gt;in&lt;/SPAN&gt; foo&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;        &lt;SPAN class=kwrd&gt;where&lt;/SPAN&gt; x &amp;gt; 0&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;        &lt;SPAN class=kwrd&gt;select&lt;/SPAN&gt; x + 1;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;This query is transformed into:&lt;/P&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;var&lt;/SPAN&gt; q = foo.Where(x =&amp;gt; x &amp;gt; 0)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;           .Select(x =&amp;gt; x + 1);&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;But what "Where" and "Select" methods are being called?&amp;nbsp; It is impossible to tell from this code snippet; it depends on what the type of "foo" is and which extension methods are in scope.&amp;nbsp; This is the beauty of query expressions and why we can do neat things like &lt;A href="http://msdn.microsoft.com/data/ref/linq/" mce_href="http://msdn.microsoft.com/data/ref/linq/"&gt;LINQ to Objects, DLINQ, and LINQ to Entities&lt;/A&gt; and so on.&amp;nbsp; Each of these providers can author their own "Where" and "Select" methods which would be called if foo was a DLINQ object or a LINQ to entities object.&amp;nbsp; If you wanted the queries to behave differently all you need to do is define your own methods such that the compiler will bind to them when you write a query.&amp;nbsp; The set of methods that needs to be implemented is called the "Query Pattern" and implementers of this pattern are called "Providers".&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Transformation Rules&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;Their are (only ;) eighteen rules that define how queries are transformed.&amp;nbsp; Here is how the transformations can be performed given that you have a query (each transformation lists the pattern that to match first and then the resultant transformation on the next line):&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;First remove query continuations.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;1.&amp;nbsp;&amp;nbsp; &lt;EM&gt;If the query has a continuation rewrite it (only rewrite the first one right now)&lt;/EM&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1 ... into x2 ...&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x2 in (from x1 in e1 ...) ...&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;Now transform the query into a list of clauses and for each clause if it is explicit then make it implicit like rules&amp;nbsp;2-4 state:&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;2.&amp;nbsp;&amp;nbsp; &lt;EM&gt;Explicit from&lt;/EM&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from T x1 in e1&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1.Cast&amp;lt;T&amp;gt;()&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;3.&amp;nbsp;&amp;nbsp; &lt;EM&gt;Explicit join&lt;/EM&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;join T x1 in e1 on k1 equals k2&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;join x1 in e1.Cast&amp;lt;T&amp;gt;() on k1 equals k2&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;4.&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;EM&gt;Explicit join into&lt;/EM&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;join T x1 in e1 on k1 equals k2 into g&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;join x1 in e1.Cast&amp;lt;T&amp;gt;() on k1 equals k2 into g&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;Now we check for the degenerate query and rewrite it in a special way.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;5.&amp;nbsp;&amp;nbsp; &lt;EM&gt;Now if the query is degenerate then do a special transform&lt;/EM&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1 select x1&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;e1.Select(x1 =&amp;gt; x1)&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;Finally, now that we have a list of clauses (without explicit types) we simply apply rules 6-18 repeatedly until we don't have a query any more.&amp;nbsp; Think of it as pattern matching.&amp;nbsp; If the list of clauses matches the given pattern then reduce the list given the transformation rule.&amp;nbsp; Rinse and Repeat.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;6.&amp;nbsp;&amp;nbsp; &lt;EM&gt;Two froms followed by a select&lt;/EM&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1 from x2 in e2 select e3&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;e1.SelectMany(x1 =&amp;gt; e2, (x1, x2) =&amp;gt; e3)&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;7.&amp;nbsp;&amp;nbsp; &lt;EM&gt;Two froms followed by a non-select&lt;/EM&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1 from x2 in e2 ...&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from * in e1.SelectMany(x1 =&amp;gt; e2, (x1, x2) =&amp;gt; new { x1, x2 }) ...&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;8.&amp;nbsp;&amp;nbsp; &lt;EM&gt;From followed by a join followed by a select&lt;/EM&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1 join x2 in e2 on k1 equals k2 select e3&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;e1.Join(e2, x1 =&amp;gt; k1, x2 =&amp;gt; k2, (x1, x2) =&amp;gt; e3)&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;9.&amp;nbsp;&amp;nbsp; &lt;EM&gt;From followed by a join followed by a non-select&lt;/EM&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1 join x2 in e2 on k1 equals k2 ...&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from * in e1.Join(e2, x1 =&amp;gt; k1, x2 =&amp;gt; k2, (x1, x2) =&amp;gt; new { x1, x2 }) ...&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;10.&amp;nbsp;&amp;nbsp; &lt;EM&gt;From followed by a join with into followed by a select&lt;/EM&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1 join x2 in e2 on k1 equals k2 into g&amp;nbsp;select e3&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;e1.GroupJoin(e2, x1 =&amp;gt; k1, x2 =&amp;gt; k2, (x1, g) =&amp;gt; e3)&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;11.&amp;nbsp;&lt;EM&gt; From followed by a join with into followed by a non-select&lt;/EM&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1 join x2 in e2 on k1 equals k2 into g&amp;nbsp;...&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from * in e1.GroupJoin(e2, x1 =&amp;gt; k1, x2 =&amp;gt; k2, (x1, g) =&amp;gt; new { x1, g }) ...&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;12.&amp;nbsp;&lt;EM&gt; From followed by orderby (for some number of keys)&lt;/EM&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1 orderby&amp;nbsp;k1, k2, k3&amp;nbsp;...&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1.OrderBy(x1 =&amp;gt; k1).ThenBy(x1 =&amp;gt; k2).ThenBy(x1 =&amp;gt; k3)&amp;nbsp;...&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;13.&amp;nbsp;&lt;EM&gt; From followed by where&lt;/EM&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1 where e2 ...&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1.Where(x1 =&amp;gt; e2) ...&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;14.&amp;nbsp; From followed by let&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1 let x2 = e2 ...&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from * in e1.Select(x1 =&amp;gt; new { x1, x2 = e2 }) ...&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;15.&amp;nbsp; &lt;EM&gt;From followed by non-identity select&lt;/EM&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1 select e2&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;e1.Select(x1 =&amp;gt; e2)&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;16.&amp;nbsp; &lt;EM&gt;From followed by identity select&lt;/EM&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1 select x1&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;e1&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;17.&amp;nbsp; &lt;EM&gt;From followed by non-identity group by&lt;/EM&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1 group e2 by e3&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;e1.GroupBy(x1 =&amp;gt; e3, x1 =&amp;gt; e2)&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;18.&amp;nbsp; &lt;EM&gt;From followed by identity group by&lt;/EM&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1 group x1 by e2&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;e1.GroupBy(x1 =&amp;gt; e2)&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;H3&gt;&lt;STRONG&gt;Example Translation&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;Consider the following query:&lt;/P&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;from&lt;/SPAN&gt; x &lt;SPAN class=kwrd&gt;in&lt;/SPAN&gt; foo&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;where&lt;/SPAN&gt; x &amp;gt; 0&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;from&lt;/SPAN&gt; y &lt;SPAN class=kwrd&gt;in&lt;/SPAN&gt; bar&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;select&lt;/SPAN&gt; x + y&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;To translate this query, we first remove check to see if rule 1 is applicable (no) and then we translate the query into a list of clauses while applying rules 2-4 (which don't apply to this query).&amp;nbsp; After rules 1-4 we have the following list of clauses.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;[from x in foo, where x &amp;gt; 0, from y in bar, select x + y]&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Rule 5 does not apply because it is not the degenerate identity select.&amp;nbsp; Now we will apply rules 6-18 repeatedly until the query is fully reduced.&amp;nbsp; The rules are always applied to the front of the list and so the first rule that is applicable is rule 13.&amp;nbsp; Which states:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1 where e2 ...&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1.Where(x1 =&amp;gt; e2) ...&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Applying this rule the list becomes:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;[from x in foo.Where(x &amp;gt; 0), from y in bar, select x + y]&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Now the next rule that is applicable is rule 6 which states:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;from x1 in e1 from x2 in e2 select e3&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;e1.SelectMany(x1 =&amp;gt; e2, (x1, x2) =&amp;gt; e3)&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The list now becomes:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;[foo.Where(x &amp;gt; 0).SelectMany(x =&amp;gt; bar, (x, y) =&amp;gt; x + y)]&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;We no longer have a query so we are done and the final rewrite looks like:&lt;/P&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;foo.Where(x =&amp;gt; x &amp;gt; 0)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;   .SelectMany(x =&amp;gt; bar, (x, y) =&amp;gt; x + y)&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;Other queries are translated in a similar fashion.&amp;nbsp; As you translate more of these,&amp;nbsp;you will notice that the rules are in fact very simple and can be easily mechanically applied.&amp;nbsp;&amp;nbsp;With some practice, you should be able to translate them quickly in your head much like doing math.&amp;nbsp; It is simply a process of&amp;nbsp;applying the rules in the right order and reaching a fixed point.&lt;/P&gt;
&lt;P&gt;You may have noticed that&amp;nbsp;rule 1 actually creates a nested query.&amp;nbsp; The rewrite rules as I explained them did not remove this nested query.&amp;nbsp; After rewriting a&amp;nbsp;query, recurse and rewrite queries found in its subexpressions.&amp;nbsp; And that is it!&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Implications&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;Interestingly, the C# spec does not specify much more than this about the semantics of query expressions; however, the rewrite rules &lt;EM&gt;do imply&lt;/EM&gt; some significant details that may not be apparent.&amp;nbsp; Some of these details include scoping rules, error message and debugging behavior, and even hidden new language features like transparent identifiers.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;&lt;EM&gt;Happy Querying!&lt;/EM&gt;&lt;/STRONG&gt;&lt;/H3&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1342764" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Queries/default.aspx">Queries</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Compilers/default.aspx">Compilers</category></item><item><title>Types of confusion</title><link>http://blogs.msdn.com/wesdyer/archive/2006/12/20/types-of-confusion.aspx</link><pubDate>Thu, 21 Dec 2006 00:06:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1333567</guid><dc:creator>wesdyer</dc:creator><slash:comments>15</slash:comments><comments>http://blogs.msdn.com/wesdyer/comments/1333567.aspx</comments><wfw:commentRss>http://blogs.msdn.com/wesdyer/commentrss.aspx?PostID=1333567</wfw:commentRss><description>&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;When I&amp;nbsp;began programming&amp;nbsp;in my early teens, I was very excited to learn about programming and also excited to become &lt;A href="http://catb.org/jargon/html/R/Real-Programmer.html" mce_href="http://catb.org/jargon/html/R/Real-Programmer.html"&gt;a&lt;/A&gt; &lt;A href="http://www.pbm.com/~lindahl/real.programmers.html" mce_href="http://www.pbm.com/~lindahl/real.programmers.html"&gt;"real"&lt;/A&gt; &lt;A href="http://en.wikipedia.org/wiki/Real_programmer" mce_href="http://en.wikipedia.org/wiki/Real_programmer"&gt;programmer&lt;/A&gt;.&amp;nbsp; I remember picking up a book from the library that purported to teach what real programmers were like.&amp;nbsp; I absorbed the material and enjoyed every page.&amp;nbsp; I can only remember a handful of things from that book which I now realize was not very serious material, but I do remember one quote:&amp;nbsp; "Strong typing is for people with weak minds."&amp;nbsp; I thought to myself, "I don't want to have a weak mind" and I didn't want people to think that I have a weak mind so I thought that I should definitely not embrace strong typing.&amp;nbsp; But what&amp;nbsp;was "strong typing" anyway, I wondered.&amp;nbsp; After much reflection on my (brief) programming experience, I decided that strong typing was using the keyboard a lot.&amp;nbsp; So I decided that people with weak minds wrote overly verbose code.&amp;nbsp; I then applied my new found principle. 
&lt;P&gt;Later I had a similar experience when I began perusing large numbers of articles, blogs, and comments about programming and programming languages.&amp;nbsp; I would routinely come across some fellow programmer who would make a statement like: "dynamic languages are better because you need to write so much less code" or "python is no good because it is weakly typed".&amp;nbsp; Furthermore, in many cases it was claimed that some language was strongly typed by one advocate and another person would claim that the same language was weakly typed.&amp;nbsp; It was obvious that my earlier misunderstanding was shared by many of my peers. 
&lt;P&gt;C# 3.0 extends and adds some wonderful language features focused on type inference.&amp;nbsp; The same confusion about what makes a language "dynamic" or "strongly typed" surrounds language features like the "var" contextual keyword. 
&lt;H3&gt;&lt;A href="http://en.wikipedia.org/wiki/Type_systems" mce_href="http://en.wikipedia.org/wiki/Type_systems"&gt;&lt;STRONG&gt;On Definitions&lt;/STRONG&gt;&lt;/A&gt;&lt;/H3&gt;
&lt;P&gt;&lt;A href="http://www.cis.upenn.edu/~bcpierce/" mce_href="http://www.cis.upenn.edu/~bcpierce/"&gt;Benjamin Pierce&lt;/A&gt;, the author of&amp;nbsp;&lt;A href="http://www.amazon.com/Types-Programming-Languages-Benjamin-Pierce/dp/0262162091" mce_href="http://www.amazon.com/Types-Programming-Languages-Benjamin-Pierce/dp/0262162091"&gt;Types and Programming Languages&lt;/A&gt;, &amp;nbsp;wrote in an email, "I spent a few weeks... trying to sort out the terminology of "strongly typed," "statically typed," "safe," etc., and found it amazingly difficult.... The usage of these terms is so various as to render them almost useless." 
&lt;P&gt;Based on the apparent confusion, I think it is best to clarify what I mean by each of the following terms. 
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;Type Checking&lt;/STRONG&gt;&amp;nbsp;- Verifying that code respects type constraints. 
&lt;P&gt;&lt;STRONG&gt;Statically Typed &lt;/STRONG&gt;- Type checking occurs at compile time. 
&lt;P&gt;&lt;STRONG&gt;Dynamically Typed &lt;/STRONG&gt;-&amp;nbsp; Type checking occurs at run time. 
&lt;P&gt;&lt;STRONG&gt;Type Safe Language &lt;/STRONG&gt;- A language which protects its own abstractions. 
&lt;P&gt;&lt;STRONG&gt;Type Unsafe&amp;nbsp;Language &lt;/STRONG&gt;- A language which is not type safe. 
&lt;P&gt;&lt;STRONG&gt;Strongly Typed and Weakly Typed &lt;/STRONG&gt;- Depends on the author; The definitions are so many and so varied that the terms are practically useless.&amp;nbsp; It seems that anyone can claim that language X is either strongly typed or weakly typed based on sound reasoning derived from one of the various definitions.&amp;nbsp; Here are a few sources: &lt;A href="http://en.wikipedia.org/wiki/Strongly-typed_programming_language" mce_href="http://en.wikipedia.org/wiki/Strongly-typed_programming_language"&gt;Wikipedia&lt;/A&gt;, &lt;A href="http://programming.reddit.com/info/t7v9/comments" mce_href="http://programming.reddit.com/info/t7v9/comments"&gt;Reddit&lt;/A&gt;, &lt;A href="http://groups.google.com/group/comp.lang.perl.moderated/browse_frm/thread/e2e153d2ad7380c5/89b5f256ea7bfadb?lnk=gst&amp;amp;q=weak+typing+author%3Amjd%40plover.com&amp;amp;rnum=1&amp;amp;hl=en#89b5f256ea7bfadb" mce_href="http://groups.google.com/group/comp.lang.perl.moderated/browse_frm/thread/e2e153d2ad7380c5/89b5f256ea7bfadb?lnk=gst&amp;amp;q=weak+typing+author%3Amjd%40plover.com&amp;amp;rnum=1&amp;amp;hl=en#89b5f256ea7bfadb"&gt;Google Groups&lt;/A&gt;, and &lt;A href="http://www.cincomsmalltalk.com/userblogs/buck/blogView?showComments=true&amp;amp;entry=3252458583" mce_href="http://www.cincomsmalltalk.com/userblogs/buck/blogView?showComments=true&amp;amp;entry=3252458583"&gt;another one&lt;/A&gt;. 
&lt;P&gt;&lt;A href="http://en.wikipedia.org/wiki/Dynamic_language" mce_href="http://en.wikipedia.org/wiki/Dynamic_language"&gt;&lt;STRONG&gt;Dynamic Language&lt;/STRONG&gt;&lt;/A&gt; - A language which enables runtime inspection or modification&amp;nbsp;of a program; most languages can do this but dynamic languages make it easy.&amp;nbsp; It is common for people to refer to "dynamic languages" and mean "dynamically typed languages" as the term is defined here. 
&lt;P&gt;&lt;A href="http://en.wikipedia.org/wiki/Type_inference" mce_href="http://en.wikipedia.org/wiki/Type_inference"&gt;&lt;STRONG&gt;Type Inference&lt;/STRONG&gt;&lt;/A&gt; - Deducing the type of an expression based upon the eventual evalution of that expression.&amp;nbsp; Type inference enables the compiler to deduce types without type annotations.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Based on&amp;nbsp;these definitions&amp;nbsp;we can tackle some common misconceptions. 
&lt;P&gt;&lt;STRONG&gt;#1 - Dynamic languages are dynamically typed&lt;/STRONG&gt; 
&lt;P&gt;Depends.&amp;nbsp; Admittedly, most people seem to use the two terms interchangeably.&amp;nbsp; But given the definitions used above then they are not the same.&amp;nbsp; It is true that many dynamic languages are dynamically typed but it is not a requirement.&amp;nbsp; It also seems to be the case that dynamic language features tend to be more easily adapted to dynamically typed languages.&amp;nbsp; However, C# can be claimed to be a dynamic language (or at least that it has dynamic language features) since it has reflection, runtime code generation (from libraries), EnC (tool based), and now it has expression tree (which can be created, type checked, and evaluated&amp;nbsp;at runtime). 
&lt;P&gt;&lt;STRONG&gt;#2 - Languages that allow programming without type annotations&amp;nbsp;are dynamically typed&lt;/STRONG&gt; 
&lt;P&gt;False.&amp;nbsp; Whether a language is dynamically typed or not depends on whether type checking happens at runtime or compile time.&amp;nbsp; Languages with type inference for example do not require type annotations but the compiler infers them (as if a programmer had typed them) and then performs type checking at compile time for consistent usage. 
&lt;P&gt;&lt;STRONG&gt;#3 - Dynamically typed&amp;nbsp;languages are more terse&lt;/STRONG&gt; 
&lt;P&gt;False.&amp;nbsp; Maybe, a claim could be made that dynamically typed languages tend to be more terse given languages like Python, Perl, and Lisp; however, the statically typed languages have some very terse representatives as well (Haskell, ML dialects). 
&lt;P&gt;&lt;STRONG&gt;#4 - Statically/Dynamically&amp;nbsp;typed languages are better than&amp;nbsp;Dynamically/Statically typed languages&lt;/STRONG&gt; 
&lt;P&gt;False.&amp;nbsp; It is hard to make this claim objectively since "better" is usually ill-defined.&amp;nbsp; There are some very good languages that are statically typed and some very good languages that are dynamically typed.&amp;nbsp; Define what "better" means here and then we can talk.&amp;nbsp; Of course, your definition of "better" may be disputed (and often is). 
&lt;P&gt;&lt;STRONG&gt;#5 - A language is either dynamically or statically typed but not both&lt;/STRONG&gt; 
&lt;P&gt;Depends.&amp;nbsp; In fact, most statically typed languages have a few features that are dynamically typed.&amp;nbsp; In C# there are several examples: array bounds checking and casting.&amp;nbsp; If you access an element outside of the bounds of an array then the error occurs at runtime because the type checking for the validity of this operation occurrsat runtime.&amp;nbsp; If you cast an object to a string when in fact it contained an int then the type system will complain at runtime.&amp;nbsp; Despite this, a language is usually referred to as being either statically or dynamically typed. 
&lt;H3&gt;&lt;STRONG&gt;The "var" contextual keyword&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;Now we are ready to look the new contextual keyword "var".&amp;nbsp; It is a very handy device that enables the programmer to omit type declarations for variables that are initialized in their declaration.&amp;nbsp; However, it should be carefully noted that this feature still uses static type checking.&amp;nbsp; For example: 
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;var x = true; // same as&amp;nbsp;bool x = "foo"&lt;/FONT&gt; 
&lt;P&gt;&lt;FONT face="Courier New"&gt;var y = 5; // same as int y = 5&lt;/FONT&gt; 
&lt;P&gt;&lt;FONT face="Courier New"&gt;y += 1; // ok&lt;/FONT&gt; 
&lt;P&gt;&lt;FONT face="Courier New"&gt;var z = x + y; // error! cannot add bool and int, won't compile&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Some people mistakenly confuse the semantics of the "var" contextual keyword with the "var" declarations used in javascript or the variant datatype in VB.&amp;nbsp; &lt;EM&gt;They are very different.&lt;/EM&gt;&amp;nbsp; Javascript is dynamically typed so when an assignment is made to a variable there is no complaint about mismatched types.&amp;nbsp; This is because&amp;nbsp;each variable does not have a type per se but a value that is assigned to a variable has a type.&amp;nbsp; So values of different types may be assigned to the same variable as long as usage of that value at runtime&amp;nbsp;is consistent with the type.&amp;nbsp; So in javascript we could do the following: 
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;var x = "foo";&lt;/FONT&gt; 
&lt;P&gt;&lt;FONT face="Courier New"&gt;x = 5; // no error here, but if this were C# code then a compile error (not a runtime error) would occur&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;I love using the new C# 3.0 "var" syntax&amp;nbsp;for declaring local variables.&amp;nbsp; In fact, it is the C# 3.0 feature that I use most frequently.&amp;nbsp; Here are several reasons to use "var": 
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;1.&amp;nbsp; In my opinion, good programming style dictates that variables should be initialized when they are declared anyway and the type can usually be deduced from the expression used to assign the variable &lt;/STRONG&gt;
&lt;P&gt;&lt;STRONG&gt;2.&amp;nbsp;&amp;nbsp;Specifying the type is often redundant&lt;/STRONG&gt; 
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;Foo&amp;nbsp;foo = new Foo();&lt;/FONT&gt; 
&lt;P&gt;&lt;STRONG&gt;3.&amp;nbsp; The programmer may not care what type a variable is as long as her usage of that variable type checks&lt;/STRONG&gt; 
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;SomeFileType&amp;nbsp;file = GetFileAttributes(filename);&lt;/FONT&gt; 
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;if (file.IsReadOnly) ...&lt;/FONT&gt; 
&lt;P&gt;&lt;STRONG&gt;4.&amp;nbsp; The programmer may not be able to specify the name of the type&lt;/STRONG&gt; 
&lt;P&gt;&lt;FONT face="courier new"&gt;???&amp;nbsp;foo = new { X = "bar", Y = 3.14159 }; // anonymous type (type which has no name)&lt;/FONT&gt; 
&lt;P&gt;&lt;STRONG&gt;5.&amp;nbsp; The type name may be very very very long &lt;/STRONG&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;Dictionary&amp;lt;Pair&amp;lt;int,List&amp;lt;Set&amp;lt;double&amp;gt;&amp;gt;&amp;gt;, Pair&amp;lt;double,int&amp;gt;&amp;gt; map = new Dictionary&amp;lt;Pair&amp;lt;int,List&amp;lt;Set&amp;lt;double&amp;gt;&amp;gt;&amp;gt;, Pair&amp;lt;double,int&amp;gt;&amp;gt;();&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Only #4 is a mandated use for "var", the other reasons are more asthetic.&amp;nbsp; A natural follow-up question is when can't I or when shouldn't I use "var". 
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;1.&amp;nbsp; When the type of the initializing expression is not the type that you want the variable to be&lt;/STRONG&gt; 
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;var x = new Bar();&lt;/FONT&gt; 
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;if (someCondition) x = new Foo(); // where Bar derives from Foo&lt;/FONT&gt; 
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;var y = null; // this doesn't work because null doesn' thave a type, although you could do var y = default(string); instead&lt;/FONT&gt; 
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;var z = (a, b) =&amp;gt; a + b; // this doesn't work because lambdas do not have a type, they must be converted to a delegate type first&lt;/FONT&gt; 
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;var y = 1;&lt;/FONT&gt; 
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;y += 1.1; // error y is int, should have been declared double or possibly initialized with 1.0&lt;/FONT&gt; 
&lt;P&gt;&lt;STRONG&gt;2.&amp;nbsp; When you want to explicitly state the type of a variable for human readability&lt;/STRONG&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;I personally don't think #2 is very compelling especially since with IDE support you can easily hover over "var" and see the type for each variable.&amp;nbsp; Furthermore, I think that some of the arguments used by the proponents of dynamically typed&amp;nbsp;languages apply here (not that this is a dynamically typed language feature).&amp;nbsp; The number of type annotations in a program can distract from the intent of the program.&amp;nbsp; From this perspective, the "var" contextual keyword actually improves readability.&amp;nbsp; But unlike a dynamically typed language, the compiler can still type check the program at compile time and provide feedback on possible errors. 
&lt;P&gt;The "var" contextual keyword is just one of several features in C# 3.0 that uses type inference.&amp;nbsp; But those features will be discussed another day.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1333567" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Languages/default.aspx">Languages</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Types/default.aspx">Types</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Saving the State of Enumerators</title><link>http://blogs.msdn.com/wesdyer/archive/2006/01/13/saving-the-state-of-enumerators.aspx</link><pubDate>Fri, 13 Jan 2006 23:51:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:512709</guid><dc:creator>wesdyer</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/wesdyer/comments/512709.aspx</comments><wfw:commentRss>http://blogs.msdn.com/wesdyer/commentrss.aspx?PostID=512709</wfw:commentRss><description>&lt;P&gt;&lt;FONT face=Verdana size=2&gt;&lt;A href="http://blogs.msdn.com/cyrusn" mce_href="http://blogs.msdn.com/cyrusn"&gt;Cyrus&lt;/A&gt; and I were writing some code together the other day and we used an interesting data structure that I wanted to share with you.&amp;nbsp; This data structure I will call a chain which is essentially a immutable singlely linked list.&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;interface&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;IChain&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt; : &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;IEnumerable&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt;&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;IChain&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt; Next { &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;get&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;T Value { &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;get&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;; }&lt;BR&gt;}&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;&lt;FONT face=Verdana size=2&gt;It is possible to provide a lot of the necessary functionality through an abstract class.&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;abstract&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;class&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;AbstractChain&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt; : &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;IChain&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt;&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;abstract&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;IChain&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt; Next { &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;get&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;; }&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;abstract&lt;/FONT&gt;&lt;FONT size=2&gt; T Value { &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;get&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;; }&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;IEnumerator&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt; GetEnumerator()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IChain&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt; current = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;this&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while&lt;/FONT&gt;&lt;FONT size=2&gt; (current != &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;null&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; current.Value;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;current = current.Next;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;System.Collections.&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;IEnumerator&lt;/FONT&gt;&lt;FONT size=2&gt; System.Collections.&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;IEnumerable&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.GetEnumerator()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;this&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;.GetEnumerator();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;&lt;FONT face="Courier New"&gt;&lt;FONT face=Verdana size=2&gt;Of course, a simple concrete Chain class has a very straightforward implementation.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;class&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Chain&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt; : &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;AbstractChain&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt;&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;IChain&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt; next;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;T value;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/FONT&gt;&lt;FONT size=2&gt; Chain(&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;IChain&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt; next, T value)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this&lt;/FONT&gt;&lt;FONT size=2&gt;.next = next;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this&lt;/FONT&gt;&lt;FONT size=2&gt;.value = value;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/FONT&gt;&lt;FONT size=2&gt; Chain(T value)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;: &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;this&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;null&lt;/FONT&gt;&lt;FONT size=2&gt;, value)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;override&lt;/FONT&gt;&lt;FONT size=2&gt; T Value&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&lt;/FONT&gt;&lt;FONT size=2&gt; { &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;return&lt;/FONT&gt;&lt;FONT size=2&gt; value; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;override&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;IChain&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt; Next&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&lt;/FONT&gt;&lt;FONT size=2&gt; { &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;return&lt;/FONT&gt;&lt;FONT size=2&gt; next; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;FONT face=Verdana&gt;In this implementation, each node contains a value and every node but the last node has a link to the next node.&amp;nbsp; The last node has a null instead of a link to the next node.&amp;nbsp; But what if I don't want to create the whole list upfront?&amp;nbsp; What if I know how to create it, but I don't want the overhead of creation and then traversal.&amp;nbsp; The solution of course is to lazily create the linked list or create it on demand.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;FONT color=#0000ff size=2&gt;class&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;LazyChain&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt; : &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;AbstractChain&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt;&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;IChain&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt; next;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;T value;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;IEnumerator&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt; enumerator;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;LazyChain(T value, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;IEnumerator&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt; enumerator)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this&lt;/FONT&gt;&lt;FONT size=2&gt;.value = value;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this&lt;/FONT&gt;&lt;FONT size=2&gt;.enumerator = enumerator;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;static&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;IChain&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt; Create(&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;IEnumerable&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt; enumerable)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/FONT&gt;&lt;FONT size=2&gt; Create(enumerable.GetEnumerator());&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;static&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;IChain&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt; Create(&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;IEnumerator&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt; enumerator)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/FONT&gt;&lt;FONT size=2&gt; (enumerator.MoveNext())&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;LazyChain&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt;(enumerator.Current, enumerator);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;null&lt;/FONT&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;override&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;IChain&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt; Next&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&lt;BR&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/FONT&gt;&lt;FONT size=2&gt; (enumerator != &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;null&lt;/FONT&gt;&lt;FONT size=2&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;next = Create(enumerator);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerator = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;null&lt;/FONT&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/FONT&gt;&lt;FONT size=2&gt; next;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;override&lt;/FONT&gt;&lt;FONT size=2&gt; T Value&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&lt;/FONT&gt;&lt;FONT size=2&gt; { &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;return&lt;/FONT&gt;&lt;FONT size=2&gt; value; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;FONT face=Verdana&gt;Notice how the constructor to a lazy chain does not take a link to the next chain, it takes an enumerator.&amp;nbsp; It uses this enumerator to create the next link when it is first accessed.&amp;nbsp; One great application where this is useful is in rollbacking an enumerator.&amp;nbsp; It is sometimes useful to be able to mark a place in the execution of an enumerator and then reset to that point and iterate again.&amp;nbsp; The lazy chain makes such behavior possible and efficient.&amp;nbsp; For an example, consider the following program.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;class&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#008080 size=2&gt;Program&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;static&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;IEnumerable&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&amp;gt; GetNumbers()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&lt;/FONT&gt;&lt;FONT size=2&gt; (&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; i = 0; i &amp;lt; 10; ++i)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; i;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;static&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; Main(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;[] args)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IChain&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;gt; intChain = &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;LazyChain&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&amp;gt;.Create(GetNumbers());&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IChain&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;gt; savedChain = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;null&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&lt;/FONT&gt;&lt;FONT size=2&gt; (&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt; i = 0; intChain != &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;null&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;; ++i)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; (intChain.Value == 5)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;savedChain = intChain;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;intChain = intChain.Next;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/FONT&gt;&lt;FONT size=2&gt; (savedChain != &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;null&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&lt;/FONT&gt;&lt;FONT size=2&gt; (&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt; i &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;in&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; savedChain)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;.WriteLine(i);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;&lt;FONT face="Courier New" size=2&gt;&lt;FONT face=Verdana&gt;Although the iterator iterates through all of the numbers, we pick execution up again where the value was five and then proceed to print out the numbers.&amp;nbsp; Furthermore, the code to iterate over the chains is ignorant of the fact of what kind of chain it is dealing with.&amp;nbsp; While this example is a bit contrived, it does illustrate the ability of the data structure to mark and continue over&amp;nbsp;enumerators while preserving immutability.&amp;nbsp; For Cyrus and I, it greatly simplified the design of a component that we were working on while preserving performance.&lt;/FONT&gt;&lt;BR&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=512709" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Design+Patterns/default.aspx">Design Patterns</category></item><item><title>captivated foreach statements</title><link>http://blogs.msdn.com/wesdyer/archive/2005/10/06/captivated-foreach-statements.aspx</link><pubDate>Thu, 06 Oct 2005 21:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:478027</guid><dc:creator>wesdyer</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/wesdyer/comments/478027.aspx</comments><wfw:commentRss>http://blogs.msdn.com/wesdyer/commentrss.aspx?PostID=478027</wfw:commentRss><description>&lt;P&gt;&lt;FONT face=Verdana size=2&gt;I am sure that most people who use C# regularly use the &lt;EM&gt;foreach &lt;/EM&gt;construct.&amp;nbsp; Intimately understanding this construct is not usually required for proper usage.&amp;nbsp; The syntax is straightforward and it would seem that the semantics would also be straightforward; however, beginning in C# 2.0 there is a subtle gotcha that can cause seemingly odd behavior.&amp;nbsp; Take this code for example:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#0000ff&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;using&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face=Verdana&gt; System;&lt;BR&gt;&lt;/FONT&gt;&lt;BR&gt;&lt;FONT face=Verdana&gt;&lt;FONT color=#0000ff&gt;class&lt;/FONT&gt; &lt;FONT color=#008080&gt;Program &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Verdana&gt;&lt;FONT size=2&gt;{&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;delegate&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; &lt;FONT color=#008080&gt;Proc&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Verdana&gt;&lt;FONT size=2&gt;();&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;static&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; Main(&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Verdana&gt;&lt;FONT size=2&gt;[] args) {&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Verdana&gt;&lt;FONT size=2&gt;[] numbers = { 0, 1, 2, 3, 4, 5 };&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Proc&lt;/FONT&gt;[] actions = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;Proc&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Verdana&gt;&lt;FONT size=2&gt;[numbers.Length];&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Verdana&gt;&lt;FONT size=2&gt; current = 0;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&lt;/FONT&gt; (&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; number &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Verdana&gt;&lt;FONT size=2&gt; numbers) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;actions[current] = &lt;FONT color=#0000ff&gt;delegate&lt;/FONT&gt; { &lt;FONT color=#008080&gt;Console&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Verdana size=2&gt;.WriteLine(number); };&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;actions[current++]();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;&lt;FONT face=Verdana size=2&gt;You would expect that this program would just list the numbers zero through five on sequential lines.&amp;nbsp; This is exactly what the program does; however, what will this slight modification do to the output:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Verdana&gt;&lt;FONT color=#0000ff&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT size=2&gt;using&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; System;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;class&lt;/FONT&gt; &lt;FONT color=#008080&gt;Program &lt;/FONT&gt;{&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;delegate&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; &lt;FONT color=#008080&gt;Proc&lt;/FONT&gt;();&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;static&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; Main(&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt;[] args) {&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&lt;/FONT&gt;[] numbers = { 0, 1, 2, 3, 4, 5 };&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Proc&lt;/FONT&gt;[] actions = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;Proc&lt;/FONT&gt;[numbers.Length];&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&lt;/FONT&gt; current = 0;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&lt;/FONT&gt; (&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; number &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; numbers) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;actions[current++] = &lt;FONT color=#0000ff&gt;delegate&lt;/FONT&gt; { &lt;FONT color=#008080&gt;Console&lt;/FONT&gt;.WriteLine(number); };&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&lt;/FONT&gt; (&lt;FONT color=#008080&gt;Proc&lt;/FONT&gt; action &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; actions) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;action();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;BR&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;&lt;FONT size=2&gt;So what is the output to this program.&amp;nbsp; It just repeats the number five on six lines.&amp;nbsp; Why?&amp;nbsp; Well, there are two important concepts to grasp.&amp;nbsp; First, how the foreach statement works and second how anonymous methods "capture" local variables.&amp;nbsp; A quick glance at the ECMA spec tells us that the foreach statement is rewritten like this:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#0000ff&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT size=2&gt;foreach&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; (T item &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; collection) {&lt;BR&gt;...statements...&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;&lt;FONT size=2&gt;becomes (if collection implements IEnumerable&amp;lt;T&amp;gt; other situations are similar)...&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#008080&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT size=2&gt;IEnumerator&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T&amp;gt; enumerator = ((&lt;FONT color=#008080&gt;IEnumerable&lt;/FONT&gt;&amp;lt;T&amp;gt;)(collection)).GetEnumerator();&lt;BR&gt;&lt;FONT color=#0000ff&gt;try&lt;/FONT&gt; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;T element;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;while&lt;/FONT&gt; (enumerator.MoveNext()) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;element = enumerator.Current;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...statements...&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;} &lt;FONT color=#0000ff&gt;finally&lt;/FONT&gt; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerator.Dispose();&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;&lt;FONT size=2&gt;Note that the declaration of element is outside of the loop.&amp;nbsp; It could have been in the loop and in most cases the placement does not matter, but the spec says that it is outside of the loop.&amp;nbsp; Now we move onto anonymous methods.&lt;/FONT&gt;&lt;/P&gt;
&lt;P dir=ltr&gt;&lt;FONT size=2&gt;Anonymous methods capture local variables by putting them on the heap instead of on the stack.&amp;nbsp; A private nested class is generated by the compiler that contains the local variables that are captured.&amp;nbsp; This class is then instantiated when the local variables come into scope.&amp;nbsp; Since the CLR does not provide native support for anonymous methods, these methods are rewritten in constructs that do exist.&amp;nbsp; Here is what the code looks like when the anonymous method and foreach statements&amp;nbsp;are rewritten.&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#0000ff&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT size=2&gt;using&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; System;&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; System.Collections;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;class&lt;/FONT&gt; &lt;FONT color=#008080&gt;Program &lt;/FONT&gt;{&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;delegate&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; &lt;FONT color=#008080&gt;Proc&lt;/FONT&gt;();&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;static&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; Main(&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt;[] args) {&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&lt;/FONT&gt;[] numbers = { 0, 1, 2, 3, 4, 5 };&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Proc&lt;/FONT&gt;[] actions = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;Proc&lt;/FONT&gt;[numbers.Length];&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&lt;/FONT&gt; current = 0;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IEnumerator&lt;/FONT&gt; enumerator1 = numbers.GetEnumerator();&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try &lt;/FONT&gt;{&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Locals1&lt;/FONT&gt; locals1 = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;Locals1&lt;/FONT&gt;();&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while&lt;/FONT&gt; (enumerator1.MoveNext()) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;locals1.number = (&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt;)enumerator1.Current;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;actions[current++] = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;Proc&lt;/FONT&gt;(locals1.Method1);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;FONT color=#0000ff&gt;finally &lt;/FONT&gt;{&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IDisposable&lt;/FONT&gt; disposable = enumerator1 &lt;FONT color=#0000ff&gt;as&lt;/FONT&gt; &lt;FONT color=#008080&gt;IDisposable&lt;/FONT&gt;;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/FONT&gt; (disposable != &lt;FONT color=#0000ff&gt;null&lt;/FONT&gt;) disposable.Dispose();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IEnumerator&lt;/FONT&gt; enumerator2 = actions.GetEnumerator();&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try &lt;/FONT&gt;{&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Proc&lt;/FONT&gt; action;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while&lt;/FONT&gt; (enumerator2.MoveNext()) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;action = (&lt;FONT color=#008080&gt;Proc&lt;/FONT&gt;)enumerator2.Current;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;action();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;FONT color=#0000ff&gt;finally &lt;/FONT&gt;{&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IDisposable&lt;/FONT&gt; disposable = enumerator2 &lt;FONT color=#0000ff&gt;as&lt;/FONT&gt; &lt;FONT color=#008080&gt;IDisposable&lt;/FONT&gt;;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/FONT&gt; (disposable != &lt;FONT color=#0000ff&gt;null&lt;/FONT&gt;) disposable.Dispose();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;class&lt;/FONT&gt; &lt;FONT color=#008080&gt;Locals1 &lt;/FONT&gt;{&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; number;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; Method1() {&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console&lt;/FONT&gt;.WriteLine(number);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;BR&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;&lt;FONT size=2&gt;Since the locals are created outside of the loop, the same instance of &lt;EM&gt;locals1&lt;/EM&gt; is being used by all of the delegates.&amp;nbsp; This leads to them all displaying the same value.&amp;nbsp; How can we fix this?&amp;nbsp; Here is how:&lt;/FONT&gt;&lt;/P&gt;
&lt;P dir=ltr&gt;&lt;FONT size=2&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; System;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;class&lt;/FONT&gt; &lt;FONT color=#008080&gt;Program &lt;/FONT&gt;{&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;delegate&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; &lt;FONT color=#008080&gt;Proc&lt;/FONT&gt;();&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;static&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; Main(&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt;[] args) {&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&lt;/FONT&gt;[] numbers = { 0, 1, 2, 3, 4, 5 };&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Proc&lt;/FONT&gt;[] actions = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;Proc&lt;/FONT&gt;[numbers.Length];&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&lt;/FONT&gt; current = 0;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&lt;/FONT&gt; (&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; number &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; numbers) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int temp = number;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;actions[current++] = &lt;FONT color=#0000ff&gt;delegate&lt;/FONT&gt; { &lt;FONT color=#008080&gt;Console&lt;/FONT&gt;.WriteLine(temp); };&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&lt;/FONT&gt; (&lt;FONT color=#008080&gt;Proc&lt;/FONT&gt; action &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; actions) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;action();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;BR&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P dir=ltr&gt;&lt;FONT size=2&gt;With our newfound knowledge, we can implement a parallelized version of the Map and ForEach methods.&amp;nbsp; First, lets start with the serial versions.&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#0000ff&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT size=2&gt;using&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; System;&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; System.Collections.Generic;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;class&lt;/FONT&gt; &lt;FONT color=#008080&gt;Program&lt;/FONT&gt; {&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;delegate&lt;/FONT&gt; T &lt;FONT color=#008080&gt;Func&lt;/FONT&gt;&amp;lt;A0,T&amp;gt;(A0 arg0);&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;delegate&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; &lt;FONT color=#008080&gt;Proc&lt;/FONT&gt;&amp;lt;A0&amp;gt;(A0 arg0);&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;static&lt;/FONT&gt; &lt;FONT color=#008080&gt;IEnumerable&lt;/FONT&gt;&amp;lt;U&amp;gt; Map&amp;lt;T,U&amp;gt;(&lt;FONT color=#008080&gt;IEnumerable&lt;/FONT&gt;&amp;lt;T&amp;gt; list, &lt;FONT color=#008080&gt;Func&lt;/FONT&gt;&amp;lt;T,U&amp;gt; func) {&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&lt;/FONT&gt; (T item &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; list) {&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; func(item);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;static&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; ForEach&amp;lt;T&amp;gt;(&lt;FONT color=#008080&gt;IEnumerable&lt;/FONT&gt;&amp;lt;T&amp;gt; list, &lt;FONT color=#008080&gt;Proc&lt;/FONT&gt;&amp;lt;T&amp;gt; proc) {&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&lt;/FONT&gt; (T item &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; list) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proc(item);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;static&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; Main() {&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&lt;/FONT&gt;[] numbers = { 0, 1, 2, 3, 4, 5 };&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&lt;/FONT&gt;&amp;lt;&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt;,&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt;&amp;gt; squareInt = &lt;FONT color=#0000ff&gt;delegate&lt;/FONT&gt;(&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; x) { &lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; x * x; };&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Proc&lt;/FONT&gt;&amp;lt;&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt;&amp;gt; displayInt = &lt;FONT color=#0000ff&gt;delegate&lt;/FONT&gt;(&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; x) { &lt;FONT color=#008080&gt;Console&lt;/FONT&gt;.WriteLine(x); };&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ForEach(Map(numbers, squareInt), displayInt);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;BR&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;&lt;FONT size=2&gt;This displays the squares of the integer values zero through five inclusively.&amp;nbsp; Now we can parallelize them.&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#0000ff&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT size=2&gt;using&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; System;&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; System.Threading;&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; System.Collections.Generic;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;class&lt;/FONT&gt; &lt;FONT color=#008080&gt;Program&lt;/FONT&gt; {&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;delegate&lt;/FONT&gt; T &lt;FONT color=#008080&gt;Func&lt;/FONT&gt;&amp;lt;A0,T&amp;gt;(A0 arg0);&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;delegate&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; &lt;FONT color=#008080&gt;Proc&lt;/FONT&gt;&amp;lt;A0&amp;gt;(A0 arg0);&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;class&lt;/FONT&gt; &lt;FONT color=#008080&gt;ThreadAdapter&lt;/FONT&gt;&amp;lt;T,U&amp;gt; {&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Thread&lt;/FONT&gt; thread;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;T input;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;U output;&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&lt;/FONT&gt;&amp;lt;T,U&amp;gt; func;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/FONT&gt; ThreadAdapter(&lt;FONT color=#008080&gt;Func&lt;/FONT&gt;&amp;lt;T,U&amp;gt; func, T input) {&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this&lt;/FONT&gt;.input = input;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this&lt;/FONT&gt;.func = func;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;thread = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;Thread&lt;/FONT&gt;(&lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;ThreadStart&lt;/FONT&gt;(Execute));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;void&lt;/FONT&gt; Execute() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;output = func(input);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/FONT&gt; &lt;FONT color=#008080&gt;Thread&lt;/FONT&gt; Thread {&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&lt;/FONT&gt; { &lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; thread; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/FONT&gt; U Output {&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&lt;/FONT&gt; { &lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; output; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;static&lt;/FONT&gt; &lt;FONT color=#008080&gt;IEnumerable&lt;/FONT&gt;&amp;lt;U&amp;gt; Map&amp;lt;T,U&amp;gt;(&lt;FONT color=#008080&gt;IEnumerable&lt;/FONT&gt;&amp;lt;T&amp;gt; list, &lt;FONT color=#008080&gt;Func&lt;/FONT&gt;&amp;lt;T,U&amp;gt; func) {&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;List&lt;/FONT&gt;&amp;lt;&lt;FONT color=#008080&gt;ThreadAdapter&lt;/FONT&gt;&amp;lt;T,U&amp;gt;&amp;gt; threads = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;List&lt;/FONT&gt;&amp;lt;&lt;FONT color=#008080&gt;ThreadAdapter&lt;/FONT&gt;&amp;lt;T,U&amp;gt;&amp;gt;();&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&lt;/FONT&gt; (T item &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; list) {&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ThreadAdapter&lt;/FONT&gt;&amp;lt;T,U&amp;gt; thread = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;ThreadAdapter&lt;/FONT&gt;&amp;lt;T,U&amp;gt;(func, item);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;threads.Add(thread);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;thread.Thread.Start();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&lt;/FONT&gt; (&lt;FONT color=#008080&gt;ThreadAdapter&lt;/FONT&gt;&amp;lt;T,U&amp;gt; thread &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; threads) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;thread.Thread.Join();&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; thread.Output;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;static&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; ForEach&amp;lt;T&amp;gt;(&lt;FONT color=#008080&gt;IEnumerable&lt;/FONT&gt;&amp;lt;T&amp;gt; list, &lt;FONT color=#008080&gt;Proc&lt;/FONT&gt;&amp;lt;T&amp;gt; proc) {&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;List&lt;/FONT&gt;&amp;lt;&lt;FONT color=#008080&gt;Thread&lt;/FONT&gt;&amp;gt; threads = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;List&lt;/FONT&gt;&amp;lt;&lt;FONT color=#008080&gt;Thread&lt;/FONT&gt;&amp;gt;();&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&lt;/FONT&gt; (T item &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; list) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;T temp = item;&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Thread&lt;/FONT&gt; thread = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;Thread&lt;/FONT&gt;(&lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;ThreadStart&lt;/FONT&gt;(&lt;FONT color=#0000ff&gt;delegate&lt;/FONT&gt; { proc(temp); }));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;threads.Add(thread);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;thread.Start();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&lt;/FONT&gt; (&lt;FONT color=#008080&gt;Thread&lt;/FONT&gt; thread &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; threads) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;thread.Join();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;static&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; Main() {&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int&lt;/FONT&gt;[] numbers = { 0, 1, 2, 3, 4, 5 };&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&lt;/FONT&gt;&amp;lt;&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt;,&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt;&amp;gt; squareInt = &lt;FONT color=#0000ff&gt;delegate&lt;/FONT&gt;(&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; x) { &lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; x * x; };&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Proc&lt;/FONT&gt;&amp;lt;&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt;&amp;gt; displayInt = &lt;FONT color=#0000ff&gt;delegate&lt;/FONT&gt;(&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; x) { &lt;FONT color=#008080&gt;Console&lt;/FONT&gt;.WriteLine(x); };&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ForEach(Map(numbers, squareInt), displayInt);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;BR&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size=2&gt;Just for kicks, we might now write this code with the new C# 3.0 syntax.&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; System;&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; System.Query;&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; System.Threading;&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; System.Collections.Generic;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;static class&lt;/FONT&gt; &lt;FONT color=#008080&gt;Extensions&lt;/FONT&gt; {&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;class&lt;/FONT&gt; &lt;FONT color=#008080&gt;ThreadAdapter&lt;/FONT&gt;&amp;lt;T,U&amp;gt; {&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Thread&lt;/FONT&gt; thread;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;T input;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;U output;&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Func&lt;/FONT&gt;&amp;lt;T,U&amp;gt; func;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/FONT&gt; ThreadAdapter(&lt;FONT color=#008080&gt;Func&lt;/FONT&gt;&amp;lt;T,U&amp;gt; func, T input) {&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this&lt;/FONT&gt;.input = input;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this&lt;/FONT&gt;.func = func;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;thread = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;Thread&lt;/FONT&gt;(&lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;ThreadStart&lt;/FONT&gt;(Execute));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;void&lt;/FONT&gt; Execute() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;output = func(input);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/FONT&gt; &lt;FONT color=#008080&gt;Thread&lt;/FONT&gt; Thread {&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&lt;/FONT&gt; { &lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; thread; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/FONT&gt; U Output {&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&lt;/FONT&gt; { &lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; output; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public static&lt;/FONT&gt; &lt;FONT color=#008080&gt;IEnumerable&lt;/FONT&gt;&amp;lt;U&amp;gt; Map&amp;lt;T,U&amp;gt;(&lt;FONT color=#0000ff&gt;this&lt;/FONT&gt; &lt;FONT color=#008080&gt;IEnumerable&lt;/FONT&gt;&amp;lt;T&amp;gt; list, &lt;FONT color=#008080&gt;Func&lt;/FONT&gt;&amp;lt;T,U&amp;gt; func) {&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;var&lt;/FONT&gt; threads = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;List&lt;/FONT&gt;&amp;lt;&lt;FONT color=#008080&gt;ThreadAdapter&lt;/FONT&gt;&amp;lt;T,U&amp;gt;&amp;gt;();&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&lt;/FONT&gt; (&lt;FONT color=#0000ff&gt;var&lt;/FONT&gt; item &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; list) {&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;var&lt;/FONT&gt; thread = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;ThreadAdapter&lt;/FONT&gt;&amp;lt;T,U&amp;gt;(func, item);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;threads.Add(thread);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;thread.Thread.Start();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&lt;/FONT&gt; (&lt;FONT color=#0000ff&gt;var&lt;/FONT&gt; thread &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; threads) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;thread.Thread.Join();&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; thread.Output;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public static&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; ForEach&amp;lt;T&amp;gt;(&lt;FONT color=#0000ff&gt;this&lt;/FONT&gt; &lt;FONT color=#008080&gt;IEnumerable&lt;/FONT&gt;&amp;lt;T&amp;gt; list, &lt;FONT color=#008080&gt;Action&lt;/FONT&gt;&amp;lt;T&amp;gt; action) {&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;var&lt;/FONT&gt; threads = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;List&lt;/FONT&gt;&amp;lt;&lt;FONT color=#008080&gt;Thread&lt;/FONT&gt;&amp;gt;();&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&lt;/FONT&gt; (&lt;FONT color=#0000ff&gt;var&lt;/FONT&gt; item &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; list) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;FONT color=#0000ff&gt;var&lt;/FONT&gt; temp = item;&lt;BR&gt;&lt;FONT color=#008080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;var&lt;/FONT&gt; thread = &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;Thread&lt;/FONT&gt;(&lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; &lt;FONT color=#008080&gt;ThreadStart&lt;/FONT&gt;(() =&amp;gt;&amp;nbsp;{ action(temp); }));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;threads.Add(thread);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;thread.Start();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&lt;/FONT&gt; (&lt;FONT color=#0000ff&gt;var&lt;/FONT&gt; thread &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; threads) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;thread.Join();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;class&lt;/FONT&gt; &lt;FONT color=#008080&gt;Program&lt;/FONT&gt; {&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;static&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;void&lt;/FONT&gt; Main() {&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&lt;/FONT&gt; numbers = new [] { 0, 1, 2, 3, 4, 5 };&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;numbers.Map(x =&amp;gt; x * x).ForEach(x =&amp;gt; { Console.WriteLine(x); });&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;&lt;FONT size=2&gt;Enjoy!&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=478027" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/wesdyer/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/wesdyer/archive/tags/C_2300_/default.aspx">C#</category></item></channel></rss>