FromDays(1))
{ }
public DateTimeRange(DateTime start,
DateTime end,
TimeSpan step)
: base(start, end)
{
this.step = step;
}
protected override DateTime GetNextValue(DateTime current)
{
return current + step;
}
}
public class Int32Range : Range
{
readonly int step;
Listing 6.9 Two classes derived from Range, to iterate over dates/times and integers
???Steps??? from
one value to
the next
F
Uses
default
step
Uses
specified
step
Uses step to
find next value
178 CHAPTER 6 Implementing iterators the easy way
public Int32Range(int start, int end)
: this (start, end, 1)
{ }
public Int32Range(int start, int end, int step)
: base(start, end)
{
this.step = step;
}
protected override int GetNextValue(int current)
{
return current + step;
}
}
If we could have specified addition (potentially using another type) as a type parameter,
we could have used a single type everywhere, which would have been neat. There
are other obvious candidates, such as SingleRange, DoubleRange, and DecimalRange,
which I haven??™t shown here. Even though we have to derive an extra class for each
type we want to iterate over, the gain over C# 1 is still tremendous. Without generics
there would have been casts everywhere (and boxing for value types, which probably
includes most types you want to use for ranges), and without iterator blocks the code
for the separate iterator type we??™d have needed would probably have been about as
long as the base class itself.
Pages:
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354