Blog/One-of-the-nicer-spots

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
--- Blog/One-of-the-nicer-spots rto 2009-02-02 09:29:14.954312 

+++ Blog/One-of-the-nicer-spots rto 2008-05-14 18:44:19 

@@ -10,7 +10,7 @@


 For instance, consider a Department containing a collection of Student(s) - in the first implementation this could be implemented as a simple vector of Student(s) (a List in .net), and you might expose the internal data structure by providing a Students property like the following:

-    #!csharp
+    #!java
        IList<Student> Students
        {
           get
@@ -24,7 +24,7 @@


 This will make the internal way that a Department class represents students completely independent of the way users of the class access them. Luckily List&lt;Student&gt; already exposes the IEnumerable&lt;&gt; interface - so, easy!

-    #!csharp
+    #!java
        IEnumerable<Student> Students
        {
           get
@@ -36,7 +36,7 @@


 What happens now is that someone comes along and says - hey! Finding out whether or not a student is in a particular Department just by traversing a list is too slow! So you decide to go with something like a Dictionary mapping from student id (SSN or something similar) to the Student object. But you still want users to be able to, simply, traverse the list of students. With a Dictionary that is not so easy, even though a Dictionary exposes the IEnumerable&lt;&gt; it does so for a special Dictionary.KeyValuePair type - which is no good for our purpose. This is where yield will help us for the first time - check out how i implement an IEnumerable&lt;Student&gt; class in 5 lines:

-    #!csharp
+    #!java
        IEnumerable<Student> Students
        {
           get
@@ -57,7 +57,7 @@


 Where it will really save your ass is if you need to traverse a tree structure sequentially, then you just yield your way on to beatiful code - no more note keeping while trying to traverse the tree correctly. Just implement something simple like the following:

-    #!csharp
+    #!java
     class TreeNode
     {
         List<TreeNode> m_children;
@@ -90,7 +90,7 @@


 P.S. I haven't even scrached the surface of what the yield keyword can do for you - there is no requirement that you can only expose data throught yield, how about an implementation of python's xrange(from,to,increment) in C#:

-    #!csharp
+    #!java
        IEnumerable<int> Range(int _from, int _to, int _increment)
        {
           for ( int i = _from; i < _to, i += _increment ) return yield i;
@@ -101,7 +101,7 @@


 Or perhaps a way to filter the output:

-    #!csharp
+    #!java
        IEnumerable<Student> Seniors
        {
           get
@@ -116,7 +116,7 @@


 Which of course is horribly specific, why not generic' it up a bit:

-    #!csharp
+    #!java
        IEnumerable<Student> FilterStudents ( Predicate<Student> _filter )
        {
           foreach ( Student student in m_students )