IEnumerable来自IEnumerator

Ras*_*sto 11 .net c# ienumerable

我写过关于习俗的文章IEnumerator.什么是最简单的方法IEnumerable呢?理想的解决方案(一行代码)将是为了这个目的有一些类.或者我必须创建自己的?

Mik*_*keP 14

遗憾的是,没有内置方法.我有这个扩展方法,我经常使用:

static IEnumerable Iterate(this IEnumerator iterator)
{
while (iterator.MoveNext())
    yield return iterator.Current;
}
Run Code Online (Sandbox Code Playgroud)

  • 请参阅我的答案,以了解更多无法通过这种方式工作的事情 (2认同)

cit*_*kid 6

在我的C#utils集合中,我有:

class Enumerable<T> : IEnumerable<T>
{
    Func<IEnumerator<T>> factory;
    public Enumerable(Func<IEnumerator<T>> factory) { this.factory = factory; }
    public IEnumerator<T> GetEnumerator() { return this.factory(); }
    IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); }
}
Run Code Online (Sandbox Code Playgroud)

这需要一个IEnumerator工厂函数,它通常可以很容易地提供,而不是单个IEnumerator实例(在第一次迭代后产生错误的结果并打破IEnumerable的语义).这避免了Marc Gravell标记的问题并建立了完整的IEnumerable行为.

我用这种方式:

IEnumerable<Fruit> GetFruits()
{
    var arg1 = ...
    return new Enumerable<Fruit>(() => new FruitIterator(arg1, arg2, ...));
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常好的解决方案 (3认同)

Mar*_*ell 5

我会以相反的方式接近这个; 虽然你可以(根据迈克P的优秀答案)包装一个调查员假装可以枚举,但有一些你不能真正做的事情 - 例如,希望(尽管,公平,不坚持)你可以从可枚举的,理想的孤立和可重复的方式获得多个枚举器.所以,如果我这样做:

Assert.AreEqual(sequence.Sum(), sequence.Sum());
Run Code Online (Sandbox Code Playgroud)

但如果您将枚举器"欺骗"为可枚举,则第二个序列将为空.或者,如果你并行执行 - 只是奇怪的.并且有一些方法可以并行处理它们 - 考虑:

Assert.IsTrue(sequence.SequenceEqual(sequence));
Run Code Online (Sandbox Code Playgroud)

这适用统计员向前在同一时间,所以如果你只拥有一个枚举,你还算泡影.

还有就是对普查员复位,但这在很大程度上是一个设计错误,不应该使用(这是即使在迭代器块抛出一个异常,如果你把它叫做规范的正式要求).

一个更好的(IMO)问题是"如何从枚举中获取枚举器",在这种情况下,答案是"调用GetEnumerator(),并记住检查以处理迭代器" - 或者更简单地说"使用foreach".