C# 如何避免迭代器方法被重新启动? 请考虑以下C块:

C# 如何避免迭代器方法被重新启动? 请考虑以下C块:,c#,linq,iterator,yield-return,C#,Linq,Iterator,Yield Return,如果您熟悉Linq和迭代器,您会注意到在foreach块的第一次迭代中,将返回结果的第一个结果,而不是第二个结果 所以,基本上这就是我的问题:我无法从迭代器方法中获取第一个值,然后在其他地方使用它,而不重新启动此方法 有人知道一些解决方法吗?只需明确地执行: bool first = true; foreach(var item in results) { if(first) { first = false; // whatever } else

如果您熟悉Linq和迭代器,您会注意到在
foreach
块的第一次迭代中,将返回结果的第一个结果,而不是第二个结果

所以,基本上这就是我的问题:我无法从迭代器方法中获取第一个值,然后在其他地方使用它,而不重新启动此方法

有人知道一些解决方法吗?

只需明确地执行:

bool first = true;
foreach(var item in results) {
    if(first) {
        first = false;
        // whatever
    } else {
        // whatever else
    }
}
或者更复杂:

using(var iter = results.GetEnumerator()) {
    if(iter.MoveNext()) {
        // do first things with iter.Current

        while(iter.MoveNext()) {
            // do non-first things with iter.Current
        }
    }
}

您需要手动迭代:

var enumerator = results.GetEnumerator();
enumerator.MoveNext();
yield return enumerator.Current; //first
while(enumerator.MoveNext())
 yield return enumerator.Current; //2nd, ...
忽略所有错误检查。。。也不要忘记处理。

您需要使用Skip

foreach(Result result in results.Skip(1))
{
   Console.WriteLine(String.Format("This is the {0} result.", resultIndex++));
   yield return result;
}
或者手动迭代结果


如果您考虑迭代器是如何实现的,那么您看到的确实是预期的行为

其他人展示了使用
foreach
循环和条件执行的方法。这实际上是一个很好的方法-但是这里有另一个选项,以防
foreach
循环由于任何原因不合适

bool isFirst = true;
foreach(Result result in results)
{
   if(isFirst)
   {
      DoAVeryImportOperationWithFirstResult(firstResult);
      isFirst = false;
   }

   Console.WriteLine(String.Format("This is the {0} result.", resultIndex++));
   yield return result;
}
using (var iterator = results.GetEnumerator())
{
    if (!iterator.MoveNext())
    {
        // Throw some appropriate exception here.
    }

    Result firstResult = iterator.Current;
    DoAVeryImportOperationWithFirstResult(firstResult);

    Console.WriteLine(String.Format("This is the {0} result.", resultIndex++));
    yield return firstResult;

    while (iterator.MoveNext())
    {
        Result result = iterator.Current;
        Console.WriteLine(String.Format("This is the {0} result.", resultIndex++));
        yield return result;
    }
}

该死请注意,这样做需要迭代源序列两次。在许多实际情况下,这是好的,但在一般情况下不是。
using (var iterator = results.GetEnumerator())
{
    if (!iterator.MoveNext())
    {
        // Throw some appropriate exception here.
    }

    Result firstResult = iterator.Current;
    DoAVeryImportOperationWithFirstResult(firstResult);

    Console.WriteLine(String.Format("This is the {0} result.", resultIndex++));
    yield return firstResult;

    while (iterator.MoveNext())
    {
        Result result = iterator.Current;
        Console.WriteLine(String.Format("This is the {0} result.", resultIndex++));
        yield return result;
    }
}