[...]
In my example, I want to be able to do something on the last loop and
process it (as I do on the previous loops) without having to rewrite the
processing code outside of the loop:
So, if I understand correctly, not only do you want to do something
special when you reach the last element of the loop, the processing of
that last element is supposed to incorporate that "something special".
In that case, yes...there's a benefit to keeping that inside the loop and
tracking a counter may be a better solution. Noting, of course, that
that's mainly because you've said you do have a valid count for the
collection and so it's reasonable to make that test without any additional
work.
One remaining point: if your processing is some significant amount of code
(more than a couple of lines, for example), then I think it would be
almost as reasonable to put the processing into a separate method and then
call it from two places: inside the loop, and then at the end.
I say "almost", because doing that actually makes the loop more awkward.
It'd have to look something like this:
Racecar racecarPrev = null;
foreach (Racecar racecar in RaceCarCollection)
{
if (racecarPrev != null)
{
ProcessItem(racecarPrev);
}
racecarPrev = racecar;
}
if (racecarPrev != null)
{
// do "something special"
ProcessItem(racecarPrev);
}
That way you don't do the "ProcessItem" work until you know whether the
item is in fact the last one or not. Since the processing is encapsulated
in a separate method, I think it's less of a problem to duplicate that
call (I definitely don't like copy-and-pasting code that does real work,
but duplicating a simple call to a method isn't so bad if it's otherwise
beneficial).
Obviously you wouldn't contort your code to work like the above if you
already have a valid count for your collection and can do the "last item"
test inside the loop. But it could be worth keeping the above arrangement
in mind for dealing with collections that don't expose a count.
Pete