IEnumerable foreach,为最后一个元素做一些不同的事情

Col*_*nic 11 .net c# ienumerable control-flow

我有一个IEnumerable<T>.我想为集合中的每个项目做一件事,除了最后一项,我想做其他事情.我怎么能整齐地编码呢?在伪代码中

foreach (var item in collection)
{
    if ( final )
    {
        g(item)
    }
    else
    {
        f(item)
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,如果我的IEnumerable是Enumerable.Range(1,4)我做f(1)f(2)f(3)g(4).NB.如果我的IEnumerable恰好是长度1,我想要g(1).

我的IEnumerable碰巧有点蹩脚,制作Count()和循环整个事情一样昂贵.

Mar*_*ell 21

既然你提到IEnumerable[<T>](不是IList[<T>]等),我们不能依赖计数等:所以我很想展开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"
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,上述技术仅适用于IEnuemerable<T>; 对于非泛型,您需要:

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"
    }
}
Run Code Online (Sandbox Code Playgroud)