|
|
Title |
Using the new foreach command.
|
Summary |
foreach is a new command for C and C++ developers new to the C# world. It allows objects to be iterated through. |
Contributor |
John McTainsh
|
Published |
13-May-2001 |
Last updated |
13-May-2001 |
|
|
Download
Sample project files - 4 Kb
Description.
Unlike C++, C# has new command called foreach Delphi developers
will be familiar with it so here is a small example of it for C++ developers.
Help explains that it is used to iterate through a collections of objects. Since
the command is very simple to used we will concentrate on building objects to
work with it. The three object we will try will be.
- A simple array.
- A very simple class implementing the minimum code to iterate through the
class.
- A more standard implementation using an inner class to perform the
iterating.
Here is the sample.
Here we see the code the iterator through the three lists. The first example also shows
how the array is defines in C# and its iteration.
using System.Collections;
...
// Setup an array
const string sFormatMask = "###,###";
int nNumLen = sFormatMask.Length;
int[] ary = new int [] { 10, 2345, 4, 238, 98765, 2 };
Console.WriteLine("Array values");
// Iterate through the array display the data
foreach( int nAryValue in ary )
{
// Format the number for display
string sNumFormatted = Int32.Format( nAryValue, sFormatMask );
Console.WriteLine( sNumFormatted.PadLeft(nNumLen) );
}
Console.WriteLine();
Console.WriteLine("Binary limits");
// Iterate through the MyRoundBinary class
MyRoundBinary mc = new MyRoundBinary();
foreach( int nAryValue in mc )
{
// Format the number for display
string sNumFormatted = Int32.Format( nAryValue, sFormatMask );
Console.WriteLine( sNumFormatted.PadLeft(nNumLen) );
}
Console.WriteLine();
Console.WriteLine("Saturdays in range");
// Iterate through the Saturdays class
Saturdays f = new Saturdays( new DateTime(2001,06,10), new DateTime(2001,07,30) );
foreach( DateTime item in f)
{
Console.WriteLine(
item.Format(
"ddd dd-MMM-yyyy ", null ) );
}
This is the output from the above code.
Array values
10
2,345
4
238
98,765
2
Binary limits
1
2
4
8
16
32
64
128
256
Saturdays in range
Sat 23-Jun-2001
Sat 30-Jun-2001
Sat 07-Jul-2001
Sat 14-Jul-2001
Sat 21-Jul-2001
Sat 28-Jul-2001
Simple iterating class.
If our needs are simple then with a little code you can create an iteratable class.
The key points are to implement IEnumerable to tell your friends that you can be
iterated and IEnumerator to do the iteration.
/// [summary]
/// This is a simple collection definition that enables an object
/// to be iterated through using the foreach command. The output
/// will be the list 1,2,4,8...,256. Usually you would seperate
/// out the IEnumerator and IEnumerable wrappers but this is
/// quite a simple implementation.
/// [/summary]
class MyRoundBinary : IEnumerable , IEnumerator
{
int m_nBinarys;
public MyRoundBinary()
{
Reset();
}
/// [summary]
/// Here we return ourselves as the Enumerator for ourselves.
/// We can do this because the Iterator is part of this class.
/// [/summary]
public MyRoundBinary GetEnumerator()
{
return this;
}
/// [summary]
/// Because this class implements it's own enumerator this
/// functaion will never be called. It would usually be called
/// by the above function.
/// [/summary]
IEnumerator IEnumerable.GetEnumerator()
{
return null;
}
// These are the three basic enumeration fucntions.
public void Reset()
{
m_nBinarys = 0;
}
public bool MoveNext()
{
if( m_nBinarys == 0 )
m_nBinarys = 1;
else
m_nBinarys = m_nBinarys << 1;
return( m_nBinarys < 257 );
}
public int Current
{
get
{
return m_nBinarys;
}
}
/// [summary]
/// Because this class implements its own enumerator, this fuction
/// is never called. The above function is called directly.
/// [/summary]
object IEnumerator.Current
{
get
{
return null;
}
}
}
The Standard iterating class.
If you are looking for the more socially acceptable implementation then you
will need to create an inner class and pass that the outer class to read its
data. This way the IEnumerator implementation is kept neatly packaged in the
inner class. When an iteration is to be performed the GetEnumerator method is
called. This method returns a new instance of the Enumerator (inner class) that
perform the iteration without bothering the outer class.
/// [summary]
/// This class creates the ability to get the Saturdays for a date range
/// the inner class implements the ability to iterate through the
/// range.
/// [/summary]
class Saturdays : IEnumerable
{
private DateTime m_dateStart;
private DateTime m_dateEnd;
// Constructor to set the date range limits
public Saturdays( DateTime dateStart, DateTime dateEnd )
{
m_dateStart = dateStart;
m_dateEnd = dateEnd;
}
// Get access to the Enumerator for Saturdays
public IEnumerator GetEnumerator()
{
return new SaturdayEnumerator(this);
}
/// [summary]
/// Inner class implementing the Enumerator to enable iterating
/// through the Saturdays.
/// [/summary]
private class SaturdayEnumerator : IEnumerator
{
private DateTime m_dateCurrent;
private Saturdays m_saturdays;
// Constructor taking the outer class
public SaturdayEnumerator(Saturdays saturdays)
{
this.m_saturdays = saturdays;
Reset();
}
// Set the next value and return true if there is more data.
public bool MoveNext()
{
m_dateCurrent = m_dateCurrent.AddDays( 7 );
return( m_dateCurrent < m_saturdays.m_dateEnd );
}
// Set the start data.
public void Reset()
{
m_dateCurrent = m_saturdays.m_dateStart;
while( m_dateCurrent.DayOfWeek != 6 )
m_dateCurrent = m_dateCurrent.AddDays( 1 );
}
// Read only access to the object data
public object Current
{
get
{
return m_dateCurrent;
}
}
}
}
|