36

正确的调用方式到底是怎样的IEnumerator.Reset

文档说:

Reset方法是为 COM 互操作性提供的。它不一定需要实施;相反,实现者可以简单地抛出一个NotSupportedException.

好吧,这是否意味着我不应该打电话给它?

使用异常进行流控制非常诱人:

using (enumerator = GetSomeExpensiveEnumerator())
{
    while (enumerator.MoveNext()) { ... }

    try { enumerator.Reset(); } //Try an inexpensive method
    catch (NotSupportedException)
    { enumerator = GetSomeExpensiveEnumerator(); } //Fine, get another one

    while (enumerator.MoveNext()) { ... }
}

这就是我们应该使用的方式吗?或者我们根本不打算从托管代码中使用它?

4

3 回答 3

57

从不; 最终这是一个错误。多次迭代序列的正确方法是.GetEnumerator()再次调用 - 即foreach再次使用。如果您的数据不可重复(或重复成本高昂),请通过.ToList()或类似方式对其进行缓冲。

迭代器块为此方法抛出异常是语言规范中的正式要求。因此,您不能依赖它工作。曾经。

于 2011-05-11T18:38:17.453 回答
8

我建议不要使用它。许多现代IEnumerable实现只会抛出异常。

获得枚举器几乎不会“昂贵”。它正在(完全)枚举它们,这可能很昂贵。

于 2011-05-11T18:35:00.070 回答
0
public class PeopleEnum : IEnumerator
{
    public Person[] _people;

    // Enumerators are positioned before the first element 
    // until the first MoveNext() call. 
    int position = -1;

    public PeopleEnum(Person[] list)
    {
        _people = list;
    }

    public bool MoveNext()
    {
        position++;
        return (position < _people.Length);
    }

    public void Reset()
    {
        position = -1;
    }

    object IEnumerator.Current
    {
        get
        {
            return Current;
        }
    }

    public Person Current
    {
        get
        {
            try
            {
                return _people[position];
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException();
            }
        }
    }
}
于 2014-04-29T10:50:45.403 回答