{"id":21253,"date":"2008-08-13T10:00:00","date_gmt":"2008-08-13T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2008\/08\/13\/the-implementation-of-iterators-in-c-and-its-consequences-part-2\/"},"modified":"2008-08-13T10:00:00","modified_gmt":"2008-08-13T10:00:00","slug":"the-implementation-of-iterators-in-c-and-its-consequences-part-2","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20080813-00\/?p=21253","title":{"rendered":"The implementation of iterators in C# and its consequences (part 2)"},"content":{"rendered":"<p><P>\nNow that you have\n<A HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2008\/08\/12\/8849519.aspx\">\nthe basic idea behind iterators<\/A>\nunder your belt, you can already answer some questions\non iterator usage.\nHere&#8217;s a scenario based on actual events:\n<\/P>\n<BLOCKQUOTE CLASS=\"m\">\n<P>\nI have an iterator that is rather long and complicated,\nso I&#8217;d like to refactor it.\nFor illustrative purposes, let&#8217;s say that the enumerator\ncounts from 1 to 100 twice.\n(In real life, of course, the iterator will not be this simple.)\n<\/P>\n<PRE>\nIEnumerable&lt;int&gt; CountTo100Twice()\n{\n int i;\n for (i = 1; i &lt;= 100; i++) {\n  yield return i;\n }\n for (i = 1; i &lt;= 100; i++) {\n  yield return i;\n }\n}\n<\/PRE>\n<P>\nAs we learned in\nProgramming&nbsp;<A HREF=\"http:\/\/en.wikipedia.org\/wiki\/101_%28number%29\">101<\/A>,\nwe can pull common code into a subroutine and call the subroutine.\nBut when I do this, I get a compiler error:\n<\/P>\n<PRE>\nIEnumerable&lt;int&gt; CountTo100Twice()\n{\n CountTo100();\n CountTo100();\n}<\/p>\n<p>void CountTo100()\n{\n int i;\n for (i = 1; i &lt;= 100; i++) {\n  yield return i;\n }\n}\n<\/PRE>\n<P>\nWhat am I doing wrong?\nHow can I move the &#8220;count to 100&#8221; into a subroutine\nand call it twice from the <CODE>CountTo100Twice<\/CODE> function?\n<\/P>\n<\/BLOCKQUOTE>\n<P>\nAs we saw last time,\niterators are not coroutines.\nThe technique above would have worked great \nhad we\n<A HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2004\/12\/31\/344799.aspx\">\nbuilt iterators out of, say, fibers<\/A>\ninstead of building them out of state machines.\nAs state machines, all <CODE>yield return<\/CODE> statements\nmust occur at the &#8220;top level&#8221;.\nSo how do you iterate with the help of subroutines?\n<\/P>\n<P>\nYou make the subroutine its own iterator\nand suck the results out from the main function:\n<\/P>\n<PRE>\nIEnumerable&lt;int&gt; CountTo100Twice()\n{\n foreach (int i in CountTo100()) yield return i;\n foreach (int i in CountTo100()) yield return i;\n}<\/p>\n<p>IEnumerable&lt;int&gt; CountTo100()\n{\n for (i = 1; i &lt;= 100; i++) {\n  yield return i;\n }\n}\n<\/PRE>\n<P>\n<B>Exercise<\/B>:\nConsider the following fragment:\n<\/P>\n<PRE>\n foreach (int i in CountTo100Twice()) {\n  &#8230;\n }\n<\/PRE>\n<P>\nExplain what happens on the 150th call to\n<CODE>MoveNext()<\/CODE> in the above loop.\nDiscuss its consequences for recursive enumerators\n(such as tree traversal).\n<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Now that you have the basic idea behind iterators under your belt, you can already answer some questions on iterator usage. Here&#8217;s a scenario based on actual events: I have an iterator that is rather long and complicated, so I&#8217;d like to refactor it. For illustrative purposes, let&#8217;s say that the enumerator counts from 1 [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-21253","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Now that you have the basic idea behind iterators under your belt, you can already answer some questions on iterator usage. Here&#8217;s a scenario based on actual events: I have an iterator that is rather long and complicated, so I&#8217;d like to refactor it. For illustrative purposes, let&#8217;s say that the enumerator counts from 1 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/21253","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=21253"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/21253\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=21253"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=21253"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=21253"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}