13.07.2015 Views

C# in Depth

C# in Depth

C# in Depth

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

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>C#</strong> 1: the pa<strong>in</strong> of handwritten iterators163List<strong>in</strong>g 6.1Code us<strong>in</strong>g the (as yet unimplemented) new collection typeobject[] values = {"a", "b", "c", "d", "e"};IterationSample collection = new IterationSample(values, 3);foreach (object x <strong>in</strong> collection){Console.WriteL<strong>in</strong>e (x);}Runn<strong>in</strong>g list<strong>in</strong>g 6.1 should (eventually) produce output of “d”, “e”, “a”, “b”, and f<strong>in</strong>ally“c” because we specified a start<strong>in</strong>g po<strong>in</strong>t of 3. Now that we know what we need toachieve, let’s look at the skeleton of the class as shown <strong>in</strong> list<strong>in</strong>g 6.2.List<strong>in</strong>g 6.2Skeleton of the new collection type, with no iterator implementationus<strong>in</strong>g System;us<strong>in</strong>g System.Collections;public class IterationSample : IEnumerable{object[] values;<strong>in</strong>t start<strong>in</strong>gPo<strong>in</strong>t;}public IterationSample (object[] values, <strong>in</strong>t start<strong>in</strong>gPo<strong>in</strong>t){this.values = values;this.start<strong>in</strong>gPo<strong>in</strong>t = start<strong>in</strong>gPo<strong>in</strong>t;}public IEnumerator GetEnumerator(){throw new NotImplementedException();}As you can see, we haven’t implemented GetEnumerator yet, but the rest of the code isready to go. So, how do we go about implement<strong>in</strong>g GetEnumerator? The first th<strong>in</strong>g tounderstand is that we need to store some state somewhere. One important aspect ofthe iterator pattern is that we don’t return all of the data <strong>in</strong> one go—the client justasks for one element at a time. That means we need to keep track of how far we’vealready gone through our array.So, where should this state live? Suppose we tried to put it <strong>in</strong> the IterationSampleclass itself, mak<strong>in</strong>g that implement IEnumerator as well as IEnumerable. At first sight,this looks like a good plan—after all, the data is <strong>in</strong> the right place, <strong>in</strong>clud<strong>in</strong>g the start<strong>in</strong>gpo<strong>in</strong>t. Our GetEnumerator method could just return this. However, there’s a bigproblem with this approach—if GetEnumerator is called several times, several <strong>in</strong>dependentiterators should be returned. For <strong>in</strong>stance, we should be able to use twoforeach statements, one <strong>in</strong>side another, to get all possible pairs of values. That suggestswe need to create a new object each time GetEnumerator is called. We could stillimplement the functionality directly with<strong>in</strong> IterationSample, but then we’d have aclass that didn’t have a clear s<strong>in</strong>gle responsibility—it would be pretty confus<strong>in</strong>g.Licensed to Rhona Hadida

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

Saved successfully!

Ooh no, something went wrong!