请考虑以下C#块:
int resultIndex = 0;
Result firstResult = results.First();
DoAVeryImportOperationWithFirstResult(firstResult);
Console.WriteLine(String.Format("This is the {0} result.", resultIndex++));
yield return firstResult;
foreach(Result result in results)
{
Console.WriteLine(String.Format("This is the {0} result.", resultIndex++));
yield return result;
}
如果您熟悉Linq和迭代器,您会注意到在foreach
块的第一次迭代中,将返回结果的第一个结果而不是第二个结果。
所以,基本上这是我的问题:我无法从迭代器方法获取第一个值,然后在其他地方使用它而不重新启动此方法。
有人知道一些解决方法吗?
答案 0 :(得分:7)
其他人已经展示了使用foreach
循环和条件执行的方法。这实际上是一种巧妙的方法 - 但是如果foreach
循环因任何原因不合适,这是另一种选择。
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;
}
}
答案 1 :(得分:3)
明确地说明一下:
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
}
}
}
答案 2 :(得分:3)
您需要手动迭代:
var enumerator = results.GetEnumerator();
enumerator.MoveNext();
yield return enumerator.Current; //first
while(enumerator.MoveNext())
yield return enumerator.Current; //2nd, ...
省略所有错误检查...也不要忘记处理。
答案 3 :(得分:3)
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;
}
答案 4 :(得分:2)
您需要使用Skip
foreach(Result result in results.Skip(1))
{
Console.WriteLine(String.Format("This is the {0} result.", resultIndex++));
yield return result;
}
或手动迭代结果。
如果您考虑如何实现迭代器,您所看到的确实是预期的行为!