<?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>GrantRi's WebLog [MS] : Iterators</title><link>http://blogs.msdn.com/grantri/archive/tags/Iterators/default.aspx</link><description>Tags: Iterators</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Iterator Usage</title><link>http://blogs.msdn.com/grantri/archive/2004/08/17/216013.aspx</link><pubDate>Tue, 17 Aug 2004 19:52:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:216013</guid><dc:creator>grantri</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/grantri/comments/216013.aspx</comments><wfw:commentRss>http://blogs.msdn.com/grantri/commentrss.aspx?PostID=216013</wfw:commentRss><wfw:comment>http://blogs.msdn.com/grantri/rsscomments.aspx?PostID=216013</wfw:comment><description>&lt;p&gt;OK, a few days ago I asked about &lt;A href="http://blogs.msdn.com/grantri/archive/2004/08/10/212268.aspx"&gt;how you used anonymous methods&lt;/a&gt;.&amp;nbsp; Thanks for the very few who responded.&amp;nbsp; I'm hoping that more people have used them than chose to respond.&amp;nbsp; Now it's time to ask about my other pet feature: Iterators.&lt;/p&gt; &lt;p&gt;How an possibly more importantly why do you use iterators?&amp;nbsp; I'm sure that a good programmer could always sit down and write a better implementation of IEnumerable/IEnumerator for their given data.&amp;nbsp; I wonder if that time is really well spent.&amp;nbsp; Ideally iterators would allow you write comparable performing code in significantly less time.&amp;nbsp; Especially if you count the time spent to debug and fix the inevitable bugs and correctness issues.&lt;/p&gt; &lt;p&gt;There are valid reasons to not use iterators, just like sometimes you need to use a for loop instead of a foreach loop.&amp;nbsp; I've bumped into these a few times, but usually I've changed other things so I can use an iterator, rather than trying to write the IEnumerable/IEnumerator code myself. I want to know how often these situations come up in real world code, and how you resolve them.&amp;nbsp; Do you change your code so you can use an iterator, or do you hand-write the enumerator?&lt;/p&gt; &lt;p&gt;I use iterators because they save me time and I have fewer bugs.&amp;nbsp; Why do you use them, or why don't you use them?&lt;/p&gt; &lt;p&gt;--Grant&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=216013" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/grantri/archive/tags/Iterators/default.aspx">Iterators</category></item><item><title>More thoughts on Iterators</title><link>http://blogs.msdn.com/grantri/archive/2004/05/07/127714.aspx</link><pubDate>Fri, 07 May 2004 07:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:127714</guid><dc:creator>grantri</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/grantri/comments/127714.aspx</comments><wfw:commentRss>http://blogs.msdn.com/grantri/commentrss.aspx?PostID=127714</wfw:commentRss><wfw:comment>http://blogs.msdn.com/grantri/rsscomments.aspx?PostID=127714</wfw:comment><description>&lt;P&gt;So I had a short email exchange with a collegue about iterators.&amp;nbsp; He mentioned that I should put in in my blog.&amp;nbsp; Seemed reasonable, so here it is:&lt;/P&gt;&lt;B&gt;
&lt;P dir=ltr&gt;
&lt;HR id=null&gt;

&lt;P&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P dir=ltr&gt;Subject:&lt;/B&gt; Iterator generated code&lt;/P&gt;
&lt;P&gt;...&lt;BR&gt;I'm looking at porting a hand-coded enumerator to use iterators (this is for a sample and maybe an article I have in mind to write about moving a production-quality collection to Whidbey)&lt;/P&gt;
&lt;P&gt;I'm decompiling the generated code with the latest .net reflector, as my IL isn't really up to much.&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;My hand-written code tries hard to implement the full contract&amp;nbsp;from the&amp;nbsp;MSDN docs for IEnumerator, i.e. stuff like&amp;nbsp;throwing &lt;A href="ms-help://MS.VSCC.2003/MS.MSDNQTR.2003APR.1033/cpref/html/frlrfsysteminvalidoperationexceptionclasstopic.htm"&gt;InvalidOperationException&lt;/A&gt;&amp;nbsp;if the underlying collection changes in both Reset and MoveNext and throwing in Current if it is past the last element.&lt;/P&gt;
&lt;P&gt;I was wondering a couple of&amp;nbsp;things&amp;nbsp;&lt;/P&gt;
&lt;P&gt;a) Will the past last element&amp;nbsp;code get added to Current (i.e. state == -1)&lt;/P&gt;
&lt;P&gt;b) Will a Reset implementation be added?&lt;BR&gt;I can imagine that in many cases, the conditionals required to get to the yield return would be sufficient as a test in MoveNext and Reset, but I'm sure there are cases when it isn't.&lt;/P&gt;
&lt;P&gt;However I guess this would require&amp;nbsp;that any&amp;nbsp;initialiser code for user state would have to move into the constructor for this to work, as docs for Reset specify that it throws if the collection has changed between creation and Reset&lt;BR&gt;...&lt;/P&gt;
&lt;HR id=null align=center width="100%" SIZE=2&gt;
&lt;B&gt;Subject:&lt;/B&gt; RE: Iterator generated code 
&lt;P&gt;a) No.&amp;nbsp; The language designers specifically wanted the Current property to be inlineable, and NEVER to throw, even if it is accessed in an invalid state (before calling MoveNext, after MoveNext has returned false, when the collection has changed, etc.).&amp;nbsp; The general reason is that most people use foreach (or some equivalent) and there should be no reason to punish them performance-wise fo rhte few people who try to call Current some other way.&lt;/P&gt;
&lt;P&gt;b) Nope.&amp;nbsp; Again Anders mainly thought that enumerables are meant to be throw-away object and should never be reset.&amp;nbsp; He even pushed the generic form of IEnumerator to not have a Reset method (I think he would have removed it from the non-generic IEnumerator if it was possible).&lt;/P&gt;
&lt;P&gt;I've often wished we had some nice syntax to say "run this code xyz for each iteration".&amp;nbsp; The classic example is checking so see if the underlying collection has changed.&amp;nbsp; Without such syntax the user has to write boiler plate code (hopefully just calling a single method) before or after every yield.&lt;/P&gt;
&lt;P&gt;--Grant&lt;/P&gt;
&lt;HR tabIndex=-1 align=center width="100%" SIZE=2&gt;
&lt;B&gt;Subject:&lt;/B&gt; RE: Iterator generated code 
&lt;P&gt;...&lt;BR&gt;Would be good to position iterators as a performance-optimized foreach-server rather than a super-strict implementation of the IEnumerable contract.&lt;BR&gt;...&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;HR tabIndex=-1 align=center width="100%" SIZE=2&gt;

&lt;P&gt;This got me thinking some more about iterators.&amp;nbsp; The frameworks often use an int as a version field to detect when a collection has changed.&amp;nbsp; This seems like a bit of overkill and isn't 100% correct because it does suffer from wrap-around (although that is almost entirely impossible short of malicious code).&amp;nbsp; So I was wondering how you could write 100% correct code and still use an iterator, and have it be clean and maintainable code.&lt;/P&gt;
&lt;P&gt;My first thought was that you shouldn't need to increment the version all the time, only when there are live enumerator objects.&amp;nbsp; My next thought was that to have maintainable code the version checking and throwing should be encapsulated into a single method.&amp;nbsp; In C/C++ I would have used a macro to wrap up the version checking with the yield statement, but in C# I'm forced to just remeber to call my checker every place I yield.&lt;/P&gt;
&lt;P&gt;Well, for the method that checks the version and throws, I have 2 choices: on the outer collection class, or as an anonymous method inside the iterator.&amp;nbsp; Somehow the anonymous methods seems cleaner (and cooler) because it fits with the notion that an iterator effectively creates an anonymous class.&lt;/P&gt;
&lt;P&gt;Now back to detecting changes.&amp;nbsp; Instead of having an int, why not have an event that fires when the collection changes.&amp;nbsp; The iterator could subscribe to it with an anonymous method as well.&amp;nbsp; Then when there are no active iterators, there is little overhead (which is faster: a null check or an interlocked increment?).&lt;/P&gt;
&lt;P&gt;So here's some quick slapped together pseudo-code:&lt;/P&gt;
&lt;HR&gt;

&lt;P&gt;&lt;CODE&gt;public class SomeCollection {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private event EventHandler CollectionChanged;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private void OnCollectionChanged() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EventHandler h = CollectionChanged;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (h != null)&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; h(this, EventArgs.Empty);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; delegate void SimpleDelegate();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IEnumerable&amp;lt;SomeType&amp;gt; MyIterator() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bool changed = false;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EventHandler changedHandler = null;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SimpleDelegate preCondition = delegate {&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; if (changed)&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; throw new InvalidOperationException(...);&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; // Possibly some other validation code here???&lt;BR&gt;&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; changedHandler = delegate {&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; changed = true;&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; // Once it's changed, we don't need to know about future changes&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; CollectionChanged -= changedHandler;&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; changed Handler = null;&lt;BR&gt;&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; try {&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; CollectionChanged += changedHandler;&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; ...&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; yield return someValue;&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; preCondition();&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; ...&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; yield return someValue;&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; preCondition();&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; ...&lt;BR&gt;&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; finally {&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; if (changedHandler != null) {&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; CollectionChanged -= changedHandler;&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; changedHandler = null;&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; }&lt;BR&gt;&amp;nbsp;&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;/CODE&gt;&lt;/P&gt;
&lt;HR&gt;

&lt;P&gt;So what do you think?&amp;nbsp; It's still not perfect because the event isn't subscribed to until the first call into MoveNext, which may happen significantly after the call to GetEnumerator.&amp;nbsp; The only way around that would be to wrap the iterator itself with another method that created the changedHandler, subscribed it and then passed in the changedHandler/preCondition pair to the real iterator method.&amp;nbsp; The down-side to that would be that if somebody called GetEnumerator twice on the same IEnumerable, both IEnumerators would share the same changedHandler/preCondition.&lt;/P&gt;
&lt;P&gt;It still does seem like an awful lot of boiler-plate code.&amp;nbsp; I might keep the notion of using an anonymous method as a way to pre and post conditions in an iterator, but using the int as a version for collections does seem to have fewer draw-backs (and a lot less boiler-plate code)...&lt;/P&gt;
&lt;P&gt;--Grant&lt;/P&gt;&lt;/SPAN&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=127714" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/grantri/archive/tags/Anonymous+Methods/default.aspx">Anonymous Methods</category><category domain="http://blogs.msdn.com/grantri/archive/tags/Iterators/default.aspx">Iterators</category></item><item><title>Remoting...</title><link>http://blogs.msdn.com/grantri/archive/2004/04/17/115407.aspx</link><pubDate>Sun, 18 Apr 2004 05:32:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:115407</guid><dc:creator>grantri</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/grantri/comments/115407.aspx</comments><wfw:commentRss>http://blogs.msdn.com/grantri/commentrss.aspx?PostID=115407</wfw:commentRss><wfw:comment>http://blogs.msdn.com/grantri/rsscomments.aspx?PostID=115407</wfw:comment><description>&lt;P&gt;First off, I don't even pretend to have a good comprehension of how remoting works.&lt;/P&gt;
&lt;P&gt;What I do know is that right now the compiler generated classes derive directly from Object, and somehow this is bad for remoting, instead they should derive from MarshalByReferenceObject.&amp;nbsp; On the surface that is a very simple change, but it has some possibly serious performance implications.&lt;/P&gt;
&lt;P&gt;Memory-wise, MBRO adds only a little bit.&amp;nbsp; Certainly not enough to outweight the benefits of better remoting.&amp;nbsp; The penalty comes when accessing fields of MBRO objects.&amp;nbsp; The penalty is that every field access gets indirected through a method call.&amp;nbsp; The method call is not needed when accessing fields off of the this pointer.&lt;/P&gt;
&lt;P&gt;With iterators, this is a non-issue because the fields are only accessed internally off of the this pointer.&amp;nbsp; Anonymous methods have the potential to be greatly impacted.&amp;nbsp; It's bad enough that a local is now heap based, but making a local access into a method call would just supprise too many people.&lt;/P&gt;
&lt;P&gt;So is there a way to have the best of both worlds: fast access and easy remoting?&amp;nbsp; Here are the two&amp;nbsp;ideas I've heard tossed around (well I guess one is mine):&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Some keyword or syntax to specify whether a given anonymous method should be MBRO.&amp;nbsp; Then you, the programmer, can clearly decide if remoting is more important than accessing locals quickly.&amp;nbsp; The problem here is what syntax?&lt;/LI&gt;
&lt;LI&gt;Base it on the containing object.&amp;nbsp; This seems like a way of allowing you to decide, but without any extra syntax.&amp;nbsp; The problem is that many classes derive from frameworks classes that have already made that decision (and probably for different reasons).&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;So here's your chance! Voice your thoughts and opinions.&amp;nbsp; Do you have a better idea?&amp;nbsp; Do you think I'm making a big deal over nothing?&lt;/P&gt;
&lt;P&gt;--Grant&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=115407" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/grantri/archive/tags/Anonymous+Methods/default.aspx">Anonymous Methods</category><category domain="http://blogs.msdn.com/grantri/archive/tags/Iterators/default.aspx">Iterators</category></item><item><title>Recursive Iterators made Iterative</title><link>http://blogs.msdn.com/grantri/archive/2004/04/08/110165.aspx</link><pubDate>Fri, 09 Apr 2004 01:41:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:110165</guid><dc:creator>grantri</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/grantri/comments/110165.aspx</comments><wfw:commentRss>http://blogs.msdn.com/grantri/commentrss.aspx?PostID=110165</wfw:commentRss><wfw:comment>http://blogs.msdn.com/grantri/rsscomments.aspx?PostID=110165</wfw:comment><description>&lt;P&gt;So I've been thinking about this, and although it seems like CS101 to transform a recursive algorithm into an iterative one, and example might be worth while.&amp;nbsp;&amp;nbsp;&amp;nbsp; The natural one to attack would be the generic binary tree traversal iterator.&amp;nbsp; So here goes!&lt;/P&gt;
&lt;P&gt;My first thought would be to use the new Queue class to keep track of parent nodes:&lt;/P&gt;
&lt;HR&gt;

&lt;P&gt; &lt;CODE&gt;public class BinaryTree&amp;lt;DataType&amp;gt; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public DataType&amp;nbsp;Data;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public BinaryTree LeftChild;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public BinaryTree RightChild;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IEnumerable&amp;lt;DataType&amp;gt; InOrder {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get {&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; // if we were smart and&amp;nbsp;had the data&lt;BR&gt;&lt;CODE&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // we could set the initial capacity to our max depth&lt;BR&gt;&lt;/CODE&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Stack&amp;lt;BinaryTree&amp;lt;DataType&amp;gt;&amp;gt;&amp;nbsp;stack = new Stack();&lt;BR&gt;&lt;/CODE&gt;&lt;CODE&gt;&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; for (BinaryTree&amp;lt;DataType&amp;gt; current = this; &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; current != null&amp;nbsp;|| stack.Count &amp;gt; 0;&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; &lt;/CODE&gt;&lt;CODE&gt;current = current.RightChild)&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; &lt;/CODE&gt;&lt;CODE&gt;{&lt;BR&gt;&lt;/CODE&gt;&lt;CODE&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; while (&lt;CODE&gt;current != null) {&lt;/CODE&gt;&lt;CODE&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp; stack.Push(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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;current = current.LeftChild;&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; }&lt;BR&gt;&lt;/CODE&gt;&lt;/CODE&gt;&lt;CODE&gt;&lt;CODE&gt;&lt;BR&gt;&lt;/CODE&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; current = stack.Pop();&lt;BR&gt;&lt;/CODE&gt;&lt;CODE&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;yield return current.Data;&lt;BR&gt;&lt;/CODE&gt;&lt;CODE&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;/CODE&gt;&lt;CODE&gt;&amp;nbsp;&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;/CODE&gt; &lt;/P&gt;
&lt;P&gt;
&lt;HR&gt;
If I did everything right, this will only allocate the 1 stack object and enough storage within that for log N references.&amp;nbsp; And no recursion!&lt;/P&gt;
&lt;P&gt;--Grant&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=110165" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/grantri/archive/tags/Iterators/default.aspx">Iterators</category></item><item><title>A good author writes better than a good developer</title><link>http://blogs.msdn.com/grantri/archive/2004/03/30/104048.aspx</link><pubDate>Tue, 30 Mar 2004 18:39:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:104048</guid><dc:creator>grantri</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/grantri/comments/104048.aspx</comments><wfw:commentRss>http://blogs.msdn.com/grantri/commentrss.aspx?PostID=104048</wfw:commentRss><wfw:comment>http://blogs.msdn.com/grantri/rsscomments.aspx?PostID=104048</wfw:comment><description>&lt;P&gt;So here's a recent MSDN article that I actually had the chance of reviewing several months ago.&amp;nbsp; They've done a much better job at capturing the good new stuff in C# than I could ever do.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://msdn.microsoft.com/vcsharp/default.aspx?pull=/msdnmag/issues/04/05/c20/default.aspx"&gt;http://msdn.microsoft.com/vcsharp/default.aspx?pull=/msdnmag/issues/04/05/c20/default.aspx&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;I do still have a few personal corrections:&lt;/P&gt;
&lt;P&gt;I commented that the internal names that the compiler generates have changed and will probably change again, and so the article should probably just mention that the name is compiler generated and not give the actual name (those that care can run ILDASM and see for themselves), but they didn't listen.&amp;nbsp; At least they did mention that is might change.&amp;nbsp; For those of you who have the community drop you'll notice that the compiler generated names&amp;nbsp;have changed from&amp;nbsp;what's in the article.&lt;/P&gt;
&lt;P&gt;I also commented that using the binary tree wasn't exactly the best example of iterators because of it's miserable performance.&amp;nbsp; Yes it is clean and neat code, but if you have a binary tree with 5000 nodes and you foreach it a few times, you can watch your machine crawl as it is forced to spend more and more time in the GC rather than running your code.&amp;nbsp;&amp;nbsp;At least&amp;nbsp;they&amp;nbsp;mentioned this potential problem (see the last paragraph before the Partial Types section).&amp;nbsp; Too bad my brain wasn't thinking and I got the numbers wrong.&amp;nbsp; It should state, &amp;#8220;approximately &lt;I&gt;n&lt;/I&gt;&lt;STRIKE&gt;/2&lt;/STRIKE&gt; iterator instantiations, where &lt;I&gt;n&lt;/I&gt; is the number of nodes in the tree.&amp;#8221;&lt;/P&gt;
&lt;P&gt;Also note the small paragraph on #pragma warning that now gives you line-level control over individual warnings!&lt;/P&gt;
&lt;P&gt;--Grant&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=104048" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/grantri/archive/tags/Anonymous+Methods/default.aspx">Anonymous Methods</category><category domain="http://blogs.msdn.com/grantri/archive/tags/Error+Messages+and+Warnings/default.aspx">Error Messages and Warnings</category><category domain="http://blogs.msdn.com/grantri/archive/tags/Iterators/default.aspx">Iterators</category></item><item><title>Some Cool New Features</title><link>http://blogs.msdn.com/grantri/archive/2004/03/26/97112.aspx</link><pubDate>Fri, 26 Mar 2004 22:03:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:97112</guid><dc:creator>grantri</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/grantri/comments/97112.aspx</comments><wfw:commentRss>http://blogs.msdn.com/grantri/commentrss.aspx?PostID=97112</wfw:commentRss><wfw:comment>http://blogs.msdn.com/grantri/rsscomments.aspx?PostID=97112</wfw:comment><description>&lt;P&gt;I've been looking over some of my last few posts and they could easily come across as if I thought iterators and anonymous methods were the worst language features every added, and will never serve a good purpose.&amp;nbsp; If anything I think the opposite (or else I wouldn't have spent so much time on them).&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&lt;BOLD&gt;&lt;STRONG&gt;Second only to generics I think iterators and anonymous methods are the coolest features added to the C# compiler.&lt;/BOLD&gt;&lt;/STRONG&gt;&lt;/EM&gt;&lt;STRONG&gt; &lt;/STRONG&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;So then why have I been writing all this negative stuff?&amp;nbsp; Well mainly because these guys are so powerful it's easy to write bad code and then blame it on the feature.&amp;nbsp; My goal is to point out their weaknesses so that you as educated developers can write clean, neat, &lt;STRONG&gt;and&lt;/STRONG&gt; efficient code, and not get burned.&amp;nbsp; I believe in general these are both very powerful features, but like most powerful things they can be quite deadly if used improperly.&amp;nbsp; Somehow I just don't feel like the MSDN docs are going to capture some of these gotchas in their 1/2 page topic on anonymous method or iterator syntax.&amp;nbsp; Also I'm already starting to see bad habits and styles floating around and the features haven't even been officially released yet!&lt;/P&gt;
&lt;P&gt;Well, if you've been itching to try them, we finally have an answer for you: Community Drops!&amp;nbsp; If you attend VSLive! or have a MSDN Universal subscription, we're sending out or first community drop.&amp;nbsp; One word of caution: this first&amp;nbsp;release was definitely date driven, so there are known bugs, but it's a lot newer than the Alpha bits a few of you already have.&amp;nbsp; I would personally recommend installing it on a 'throw away machine' (i.e. a machine you don't mind re-installing the OS on just to clean things up), but go out and try it.&amp;nbsp; Hopefully the higher-ups will come up with a sane schedule for us releasing more frequent drops like this.&amp;nbsp; Enjoy!&lt;/P&gt;
&lt;P&gt;&lt;A href="http://msdn.microsoft.com/vs2005/"&gt;http://msdn.microsoft.com/vs2005/&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;--Grant&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=97112" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/grantri/archive/tags/Anonymous+Methods/default.aspx">Anonymous Methods</category><category domain="http://blogs.msdn.com/grantri/archive/tags/Iterators/default.aspx">Iterators</category></item><item><title>Recursive Iterators (aka Perf killers)</title><link>http://blogs.msdn.com/grantri/archive/2004/03/24/95787.aspx</link><pubDate>Thu, 25 Mar 2004 06:25:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:95787</guid><dc:creator>grantri</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/grantri/comments/95787.aspx</comments><wfw:commentRss>http://blogs.msdn.com/grantri/commentrss.aspx?PostID=95787</wfw:commentRss><wfw:comment>http://blogs.msdn.com/grantri/rsscomments.aspx?PostID=95787</wfw:comment><description>&lt;P&gt;Technically this isn't specific to iterators, but its so much easier to do with iterators that I thought I'd mention it.&amp;nbsp; Some languages are smart enough to 'flatten' iterators, such that if an iterator is called insde of another iterator, only one iteration object exists.&amp;nbsp; C# is not one of those languages (at least not yet).&amp;nbsp; Generally if you see any sort of recursion inside an iterator, you're asking for performance problems, simply because each time it recurses, it's going to create a whole new iteration object on the GC heap.&lt;/P&gt;
&lt;P&gt;Consider this binary tree:
&lt;HR&gt;
&lt;CODE&gt;public class BinaryTree&amp;lt;DataType&amp;gt; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public DataType&amp;nbsp;Data;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public BinaryTree LeftChild;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public BinaryTree RightChild;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IEnumerable&amp;lt;DataType&amp;gt; InOrder {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get {&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; if (LeftChild != null)&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; foreach (DataType d in LeftChild.InOrder)&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;&amp;nbsp;&amp;nbsp; yield return d;&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; yield return Data;&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; if (RightChild != null)&lt;/CODE&gt;&lt;CODE&gt;&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; foreach (DataType d in RightChild.InOrder)&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;&amp;nbsp;&amp;nbsp; yield return d;&lt;BR&gt;&amp;nbsp;&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;/CODE&gt;
&lt;HR&gt;
&lt;/P&gt;
&lt;P&gt; &lt;/P&gt;
&lt;P&gt;Now assume the class is properly done up with properties, and accessors and is always kept balanced.&amp;nbsp; How many objects are created when walking different sized trees?&amp;nbsp; With just 1 element, the answer is 1.&amp;nbsp; With 2 you get 2, 3 -&amp;gt; 3, 4 -&amp;gt; 4, 5 -&amp;gt; 5, etc.&amp;nbsp; You can keep doing the math, but allocation wise, this neat, clean, and simple code is O(n).&amp;nbsp; That's a pretty heavy burden on the CG if you ask me.&amp;nbsp; If that's a tax you're willing to bear, then by all means keep this clean and clear code.&lt;/P&gt;
&lt;P&gt;--Grant&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=95787" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/grantri/archive/tags/Iterators/default.aspx">Iterators</category></item><item><title>Anonymous method (and Iterator) perf</title><link>http://blogs.msdn.com/grantri/archive/2004/03/19/93094.aspx</link><pubDate>Sat, 20 Mar 2004 05:09:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:93094</guid><dc:creator>grantri</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/grantri/comments/93094.aspx</comments><wfw:commentRss>http://blogs.msdn.com/grantri/commentrss.aspx?PostID=93094</wfw:commentRss><wfw:comment>http://blogs.msdn.com/grantri/rsscomments.aspx?PostID=93094</wfw:comment><description>&lt;P&gt;probably a few of you hav asked how to make iterators and anonymous methods fast.&amp;nbsp; Well hopefully if you understand how the compiler translates them, it should be relatively easy to optimize them.&amp;nbsp; The first thing to remember is that for all practical purposes the&amp;nbsp;C# compiler does not have an optimizer.&amp;nbsp; Thus the code that you write is fairly directly translated into IL.&amp;nbsp; The best way to optimize the IL is to optimize your code.&amp;nbsp; In the case of iterators and anonymous methods, I've tried (and I think this was the language designers' intent as well) to make the transformations farily transparent, so that the programmer can easily write educated and efficient code while taking advantage of these great features.&amp;nbsp; So here's my rules for making effecient anonymous methods and iterators (in no particular order):&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Think carefully about which locals you use (a.k.a. capture).&amp;nbsp; As soon as you touch a local in an anonyous method, that local becomes heap based and goes through an extra level of indirection (and prevent enregistering).&lt;/LI&gt;
&lt;LI&gt;Think carefully about where locals are declared.&amp;nbsp; In order to maintain proper scoping semantics the compiler creates a new heap object on entry of each scope that has captured locals.&amp;nbsp; If you can move all the captured locals into one scope you'll probably get better perf.&amp;nbsp; If possible move that scope 'inward' to avoid an&amp;nbsp;GC object creation on a hot path (assuming the anonymous method is not on the hot path).&amp;nbsp; If possible move that scope out of loops&amp;nbsp;to avoid GC object creations on each iteration of the loop.&lt;/LI&gt;
&lt;LI&gt;The captured locals do not have to be in the same scope as the anonymous method.&amp;nbsp; The delegate that holds the anonymous method will be cached at the scope of the innermost captured local.&amp;nbsp; Thus if the locals are outside of a loop, but the anonymous method is inside, that's OK.&lt;/LI&gt;
&lt;LI&gt;Add extra scopes as hints to the compiler about lifetimes.&amp;nbsp; For iterators, any scopes without a 'yield return' statement will be mostly left intact, including using real locals for everytihg in that scope instead of heap-based fields.&lt;/LI&gt;
&lt;LI&gt;For iterators, if a try/finally block contains a yield statement, the finally block must be cloned from the MoveNext method into the Dispose method (so the same code is in two places).&lt;/LI&gt;
&lt;LI&gt;For iterators, calling GetEnumerator twice is just as expensive as calling the original iterator method/property/indexer twice.&lt;/LI&gt;
&lt;LI&gt;Iterators are designed to help amortize the cost of enumerations, so if you only need the first few elements, you don't need to pay the price for enumerating everything.&amp;nbsp; Follow that pattern in your own iterators where possible.&lt;/LI&gt;
&lt;LI&gt;Don't enumerate something twice when once will do.&amp;nbsp; Most enumerations have another method to obtain the count of elements without iterating.&amp;nbsp; So use that instead of iterating once just to count the elements, and then again to extract the values.&lt;/LI&gt;
&lt;LI&gt;Anonymous methods make some algorithms clearer, and iterators tend to make more correct IEnumerable/IEnumerator implementations, but neither of them will never be as efficient as hand written code (or hand written assembler, but who has time for that anymore).&amp;nbsp; So write well documented, clear, clean code, and then use a profiler to see if you need a speed improvement.&amp;nbsp; And remember that a faster algorithm will probably trump any micro-optimizations in your code (like counting down instead of up to avoid that one extra opcode on th eloop test)&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;I'm sure I think of more later, but that's most of them for now.&amp;nbsp; Enjoy, and feel free to correct me.&amp;nbsp; I can't wait until you guys can get a newer build and see the stuff we've been working on for almost the last year.&lt;/P&gt;
&lt;P&gt;--Grant&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=93094" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/grantri/archive/tags/Anonymous+Methods/default.aspx">Anonymous Methods</category><category domain="http://blogs.msdn.com/grantri/archive/tags/Iterators/default.aspx">Iterators</category></item></channel></rss>