IEnumerable foreach, do something different for the last element

.net, c#, control-flow, ienumerable

Solution

Since you mention `IEnumerable[<T>]` (not `IList[<T>]` etc), we can't rely on counts etc: so I would be tempted to unroll the `foreach`:

using(var iter = source.GetEnumerator()) {
    if(iter.MoveNext()) {
        T last = iter.Current;
        while(iter.MoveNext()) {
            // here, "last" is a non-final value; do something with "last"
            last = iter.Current;
        }
        // here, "last" is the FINAL one; do something else with "last"
    }
}

Note the above is technically only valid for `IEnuemerable<T>`; for non-generic, you'd need:

var iter = source.GetEnumerator();
using(iter as IDisposable) {
    if(iter.MoveNext()) {
        SomeType last = (SomeType) iter.Current;
        while(iter.MoveNext()) {
            // here, "last" is a non-final value; do something with "last"
            last = (SomeType) iter.Current;
        }
        // here, "last" is the FINAL one; do something else with "last"
    }
}

Problem

I have an `IEnumerable<T>`. I want to do one thing for each item of the collection, except the last item, to which I want to do something else. How can I code this neatly? In Pseudocode ``` foreach (var item in collection) { if ( final ) { g(item) } else { f(item) } } ``` So if my IEnumerable were `Enumerable.Range(1,4)` I'd do f(1) f(2) f(3) g(4). NB. If my IEnumerable happens to be length 1, I want g(1). My IEnumerable happens to be kind of crappy, making `Count()` as expensive as looping over the whole thing.

Original source