有没有办法记住一个普查员的位置? 我想记住枚举的位置,以便我可以将它重置到当前位置之前。我不想回到开头所以.reset()没有帮助。 顺便说一句,是否有可能让枚举器开始,例如在2.位置?
List<string> list = new List<string>(new string[] { "a", "b", "c" });
IEnumerator<string> i = list.GetEnumerator();
i.MoveNext(); richTextBoxOutput.AppendText(i.Current);
IEnumerator<string> t = i; // how do I make a real copy i?
i.MoveNext(); richTextBoxOutput.AppendText(i.Current);
i = t;
i.MoveNext(); richTextBoxOutput.AppendText(i.Current);
答案 0 :(得分:1)
答案 1 :(得分:0)
你肯定需要一个IEnumerator实例吗?为什么不枚举使用索引并将其存储在您自己的变量中?
var list = new List<string>(new { "a", "b", "c" });
var pos = 2; // this is the position
richTextBoxOutput.AppendText(list[pos]);
您可以随时重置:
pos = (desired position);
答案 2 :(得分:0)
有没有办法记住枚举器的位置?
有时。这取决于枚举器的实现方式。
在这种情况下,枚举器被实现为一个可变的struct
,这是一种性能优化,人们在产生这种&#34;冻结位置时会经常遇到这种情况。在他们不想要它的情况下的行为。 (如果你曾经写过包含IEnumerable<T>
实现的泛型类,那么要么将该引用保存为接口类型而不是类型本身,要么不要使用readonly
即使它看起来应该如此,如果你这样做,你最终可能会永久冻结这样的结构枚举器。)
只需更改代码,而不是:
IEnumerator<string> i = list.GetEnumerator();
…
IEnumerator<string> t = i;
你有:
List<string>.Enumerator i = list.GetEnumerator();
…
List<string>.Enumerator t = i;
或者简单地说:
var i = list.GetEnumerator();
…
var t = i;
现在,根据此i
定义了t
和struct
,并从一个复制到另一个复制了struct
,而不仅仅是对框struct
的引用{1}}。
这对所有调查员都不起作用,因此在编写自己的调查员时,不是故意让它可用的最好方法(如果你需要这样做,你最好添加一些对Clone()
而不是Snapshot()
的枚举数排序class
或struct
方法,但它适用于List<T>
。
一个更灵活的解决方案并不依赖于这样一个实施的怪癖:
public class SnapshotableListEnumerator<T> : IEnumerator<T>
{
private readonly IList<T> _list;
private int _idx;
private SnapshotableListEnumerator(IList<T> list, int idx)
{
_list = list;
_idx = idx;
}
public SnapshotableListEnumerator(IList<T> list)
: this(list, -1)
{
}
public bool MoveNext()
{
// Note that this enumerator doesn't complain about the list
// changing during enumeration, but we do want to check that
// a change doesn't push us past the end of the list, rather
// than caching the size.
if(_idx >= _list.Count)
return false;
++_idx;
return true;
}
public void Reset()
{
_idx = -1;
}
public T Current
{
get
{
if(_idx < 0 || _idx >= _list.Count)
throw new InvalidOperationException();
return _list[_idx];
}
}
object IEnumerator.Current
{
get { return Current; }
}
public void Dispose()
{
}
public SnapshotableListEnumerator<T> Snapshot()
{
return new SnapshotableListEnumerator<T>(_list, _idx);
}
}
public static class SnapshotableListEnumeratorHelper
{
public static SnapshotableListEnumerator<T> GetSnapshotableEnumerator<T>(this IList<T> list)
{
return new SnapshotableListEnumerator<T>(list);
}
}
现在,您可以在GetSnapshotableEnumerator()
的任何实现上调用IList<T>
,并在需要枚举中的位置副本时使用其Snapshot()
方法。