2

我想使用 anIEnumerable来生成一系列值——特别是类似 Excel 的列标题列表。

private IEnumerable<string> EnumerateSymbolNames()
{
  foreach (var sym in _symbols)
  {
    yield return sym;
  }

  foreach (var sym1 in _symbols)
  {
    foreach (var sym2 in _symbols)
    {
      yield return sym1 + sym2;
    }
  }

  yield break;
}
private readonly string[] _symbols = new string[] { "A", "B", "C", ...};

如果我从foreach循环中获取值,这可以正常工作。但我想要的是使用迭代器块作为状态机并获取下一个可用的列标题以响应用户操作。而这——消耗生成的值——是我遇到麻烦的地方。

到目前为止我已经尝试过

return EnumerateSymbolNames().Take(1).FirstOrDefault();

return EnumerateSymbolNames().Take(1).SingleOrDefault();

return EnumerateSymbolNames().FirstOrDefault();

var enumerator = EnumerateSymbolNames().GetEnumerator();
enumerator.MoveNext();
return enumerator.Current;

...但这些都没有奏效。(所有都重复返回“A”。)基于对这个问题的回答,我想知道我想要的甚至是可能的——尽管对该帖子的一些回复提出了与我上一个类似的技术。

不,这不是家庭作业:)

4

3 回答 3

4

使用 时GetEnumerator,每次迭代都需要使用相同的枚举器。如果您第二次调用 GetEnumerator,它将在集合的开头重新开始。

如果要使用Take,则必须首先Skip确定已处理的记录数。

于 2012-09-18T12:49:47.740 回答
0

这段代码对我有用......

var states = EnumerateSymbolNames();
var stateMachine = states.GetEnumerator();

do
{
  //something
} while (stateMachine.MoveNext());

在该循环中打印结果时,它成功生成了以下输出:

A
B
C
...
AA
AB
AC
...
BA
BB
...

这就是我认为你的意图......

于 2012-09-18T13:18:55.080 回答
0

正如@cadrell0 的回答和@Mr Steak 的评论所指出的那样,我需要做的是保留对EnumerateSymbolNames().GetEnumerator().

当您处于foreach循环中时,这是为您隐式完成的:迭代器变量包装了一个枚举器,它(我假设)在循环的本地范围内。所以 - 这是关键部分 - 当迭代器块(相当于)

enumerator.MoveNext();
return enumerator.Current;

...您总是使用相同的枚举器。而我所做的是每次都创建/获取一个不同的(新的)枚举器。可以预见的是,它总是从序列中的第一个位置开始。除了我之外,这对所有人来说可能都很明显;事后看来,这对我来说也很明显。(我认为枚举器是序列的一种单例属性,假设我每次都会得到相同的枚举器。)

以下是我想要的:

public class SymbolGenerator
{
    private readonly string[] _symbols = { "A", "B", "C", ... };

    private readonly IEnumerator<string> _enumerator;

    public SymbolGenerator()
    {
        _enumerator = EnumerateSymbols().GetEnumerator();
    }

    public string GetNextSymbol()
    {
        _enumerator.MoveNext();
        return _enumerator.Current;
    }

    private IEnumerable<string> EnumerateSymbols()
    {
        // (unchanged)
    }
}
于 2012-09-29T16:14:14.037 回答