Yield is a new syntax word within the .net 2 language. This allows for the IEnumerable interface to have direct interaction instead of using the IEnumerator interface to iterate though a result set. For easier demonstration, I think, the code examples, the first code is a .net 1 version of the interface IEnumerable.
using System;
using System.Collections;
// the inital class is IEnumerable- means that it has to implement the GetEnumerator
public class Class : IEnumerable
{
// internal class to implement the IEnumerator interface, which inturn has to do the MoveNext, Current, Reset methods.
private class ClassEnumerator : IEnumerator
{
// internal values to go through the array
private int index = -1;
private Class P;
// setup the internal variable
public ClassEnumerator(Class P)
{
this.P = P;
}
// move within the array, if any values are present.
public bool MoveNext()
{
index++;
return index < P._Names.Length;
}
// set the internal to -1, thus restart
public void Reset()
{
index = -1;
}
// get the Current object
public object Current
{
get
{
return P._Names[index];
}
}
}
// return a IEnumerator object of the above with itself passed
public IEnumerator GetEnumerator()
{
return new ClassEnumerator(this);
}
// the internal string array of names
private string[] _Names;
// the new class setup process,
public Class(params string[] Names)
{
_Names = new string[Names.Length];
// copy the passed parameter starting at position 0
Names.CopyTo(_Names,0);
}
}
class ClassProgram
{
static void Main(string[] args)
{
Class ClassArr = new Class("Student1", "Student2","Studentx");
foreach (string s in ClassArr)
Console.WriteLine(s);
}
} |
using System;
using System.Collections;
// the inital class is IEnumerable- means that it has to implement the GetEnumerator
public class Class : IEnumerable
{
// internal class to implement the IEnumerator interface, which inturn has to do the MoveNext, Current, Reset methods.
private class ClassEnumerator : IEnumerator
{
// internal values to go through the array
private int index = -1;
private Class P;
// setup the internal variable
public ClassEnumerator(Class P)
{
this.P = P;
}
// move within the array, if any values are present.
public bool MoveNext()
{
index++;
return index < P._Names.Length;
}
// set the internal to -1, thus restart
public void Reset()
{
index = -1;
}
// get the Current object
public object Current
{
get
{
return P._Names[index];
}
}
}
// return a IEnumerator object of the above with itself passed
public IEnumerator GetEnumerator()
{
return new ClassEnumerator(this);
}
// the internal string array of names
private string[] _Names;
// the new class setup process,
public Class(params string[] Names)
{
_Names = new string[Names.Length];
// copy the passed parameter starting at position 0
Names.CopyTo(_Names,0);
}
}
class ClassProgram
{
static void Main(string[] args)
{
Class ClassArr = new Class("Student1", "Student2","Studentx");
foreach (string s in ClassArr)
Console.WriteLine(s);
}
}
This is able to output a string of
Student1
Student2
Studentx
Since the Class class (it is a class of students), there is allot of code to iterate with the foreach function.
Within .net 2 there is a nice and more tighter method called yield, an yield will yield a result and be able to iterate though a result set with the IEnumerable return set. Again, here is the source code.
using System;
using System.Collections;
class yielding
{
// same as the class as in .net 1 version.
public class Class : IEnumerable
{
// but only need to implement this one method to do the same as the pervious separate class
public IEnumerator GetEnumerator()
{
int counter = -1;
while (counter++ < (_Names.Length-1))
yield return _Names[counter];
}
// same as the other .net 1 class internals for the private variable and the constructor
private string[] _Names;
public Class(params string[] Names)
{
_Names = new string[Names.Length];
Names.CopyTo(_Names,0);
}
}
static void Main(string[] args)
{
// same as the .net 1 version
Class ClassArr = new Class("Student1", "Student2", "Studentx");
foreach (string s in ClassArr)
Console.WriteLine(s);
}
} |
using System;
using System.Collections;
class yielding
{
// same as the class as in .net 1 version.
public class Class : IEnumerable
{
// but only need to implement this one method to do the same as the pervious separate class
public IEnumerator GetEnumerator()
{
int counter = -1;
while (counter++ < (_Names.Length-1))
yield return _Names[counter];
}
// same as the other .net 1 class internals for the private variable and the constructor
private string[] _Names;
public Class(params string[] Names)
{
_Names = new string[Names.Length];
Names.CopyTo(_Names,0);
}
}
static void Main(string[] args)
{
// same as the .net 1 version
Class ClassArr = new Class("Student1", "Student2", "Studentx");
foreach (string s in ClassArr)
Console.WriteLine(s);
}
}
Far less code and also the result is exactly the same.
Also there are other benefits of the yield attached to an IEnumerable interface, here is some more code to demonstrate how to implement a power function to display the power result being built up. This demonstrates how to use just a single method to return an iterate-able result.
using System;
using System.Collections;
class yielding
{
// same as the class as in .net 1 version.
public class Class : IEnumerable
{
// but only need to implement this one method to do the same as the pervious separate class
public IEnumerator GetEnumerator()
{
int counter = -1;
while (counter++ < (_Names.Length-1))
yield return _Names[counter];
}
// same as the other .net 1 class internals for the private variable and the constructor
private string[] _Names;
public Class(params string[] Names)
{
_Names = new string[Names.Length];
Names.CopyTo(_Names,0);
}
}
// IEnumerable linked to yield is new in .net 2, it allows for the
// iteration of this method, acting like array instead of a single return.
public static IEnumerable Power(int number, int exp)
{
int counter = 0, result = 1; // setup the default values.
while (counter++ < exp) // increament counter and whilst lower than the passed parameter exp
{
result *= number; // result = result * number;
yield return result; // yield the result and return
}
}
// can also just iterate though a array of strings (in this example)
public static IEnumerable StReturn(params string[] names)
{
int counter = -1;
while (counter++ < (names.Length-1))
yield return names[counter];
}
static void Main(string[] args)
{
// can do a return of a power function as well
foreach(int e in Power(4,3))
Console.WriteLine(e.ToString());
// you can just iterate a string
string[] st = {"student1","student2","studentx"};
foreach(string s in StReturn(st))
Console.WriteLine(s.ToString());
// same as the .net 1 version
Class ClassArr = new Class("Student1", "Student2", "Studentx");
foreach (string s in ClassArr)
Console.WriteLine(s);
}
} |
using System;
using System.Collections;
class yielding
{
// same as the class as in .net 1 version.
public class Class : IEnumerable
{
// but only need to implement this one method to do the same as the pervious separate class
public IEnumerator GetEnumerator()
{
int counter = -1;
while (counter++ < (_Names.Length-1))
yield return _Names[counter];
}
// same as the other .net 1 class internals for the private variable and the constructor
private string[] _Names;
public Class(params string[] Names)
{
_Names = new string[Names.Length];
Names.CopyTo(_Names,0);
}
}
// IEnumerable linked to yield is new in .net 2, it allows for the
// iteration of this method, acting like array instead of a single return.
public static IEnumerable Power(int number, int exp)
{
int counter = 0, result = 1; // setup the default values.
while (counter++ < exp) // increament counter and whilst lower than the passed parameter exp
{
result *= number; // result = result * number;
yield return result; // yield the result and return
}
}
// can also just iterate though a array of strings (in this example)
public static IEnumerable StReturn(params string[] names)
{
int counter = -1;
while (counter++ < (names.Length-1))
yield return names[counter];
}
static void Main(string[] args)
{
// can do a return of a power function as well
foreach(int e in Power(4,3))
Console.WriteLine(e.ToString());
// you can just iterate a string
string[] st = {"student1","student2","studentx"};
foreach(string s in StReturn(st))
Console.WriteLine(s.ToString());
// same as the .net 1 version
Class ClassArr = new Class("Student1", "Student2", "Studentx");
foreach (string s in ClassArr)
Console.WriteLine(s);
}
}
I have also include the code from above to demonstrate the similar usage for iterate though a string array.
Output would be
4
16
64
student1
student2
studentx
Student1
Student2
Studentx
You will need to have .net 2 installed or mono (use the gmcs part of mono to use the .net 2 functions.