如何正确地致电IEnumerator.Reset
?
文档说:
为COM互操作性提供了
Reset
方法。它不一定需要实施;相反,实施者可以简单地抛出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()) { ... }
}
我们应该如何使用它?或者我们不打算在托管代码中使用它吗?
答案 0 :(得分:46)
的从未强> 的;最终这是一个错误。不止一次迭代序列的正确方法是再次调用.GetEnumerator()
- 即再次使用foreach
。如果您的数据不可重复(或重复费用很高),请通过.ToList()
或类似方式对其进行缓冲。
语言规范中的正式要求是迭代器块为此方法抛出异常。因此, 不能依赖它 。如初。
答案 1 :(得分:8)
我建议不要使用它。很多现代IEnumerable
实现只会抛出异常。
获取调查员几乎不“昂贵”。它全部(完全)枚举它们可能很昂贵。
答案 2 :(得分:1)
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();
}
}
}
}