最优雅的方式来处理第一个IEnumerable项目不同

dil*_*ert 7 linq ienumerable skip

在不必对每次迭代进行测试的情况下,处理第一个IEnumerable项目的最优雅方式是什么?

通过对每次迭代的测试,它看起来像这样:

// "first item done" flag
bool firstDone = false;

// items is an IEnumerable<something>
foreach (var item in items)
{
    if (!firstDone)
    {
        // do this only once
        ProcessDifferently(item);
        firstDone = true;
        continue;
    }

    ProcessNormally(item);
}
Run Code Online (Sandbox Code Playgroud)

如果我这样做:

ProcessDifferently(items.First());
ProcessNormally(items.Skip(1)); // this calls `items.GetEnumerator` again
Run Code Online (Sandbox Code Playgroud)

它将调用GetEnumerator两次,我想避免(例如,Linq-to-Sql情况).

如果你需要在你的代码周围做几次,你会怎么做?

Jon*_*eet 12

如果我需要在几个地方做,我会提取一个方法:

public void Process<T>(IEnumerable<T> source,
                       Action<T> firstAction,
                       Action<T> remainderAction)
{
    // TODO: Argument validation
    using (var iterator = source.GetEnumerator())
    {
        if (iterator.MoveNext())
        {
            firstAction(iterator.Current);
        }
        while (iterator.MoveNext())
        {
            remainderAction(iterator.Current);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

被称为:

Process(items, ProcessDifferently, ProcessNormally);
Run Code Online (Sandbox Code Playgroud)

还有其他选择,但这实际上取决于具体情况.