I have requirement in which I have to back and fort开发者_如何学Go with record. So I am using IEnumerator to that. But I can move forward by movenext but there no way to move back
Here's one way you could wrap an IEnumerator<T>
, by capturing its contents in a List<T>
as it moves along:
public interface ITwoWayEnumerator<T> : IEnumerator<T>
{
bool MovePrevious();
}
public class TwoWayEnumerator<T> : ITwoWayEnumerator<T>
{
private IEnumerator<T> _enumerator;
private List<T> _buffer;
private int _index;
public TwoWayEnumerator(IEnumerator<T> enumerator)
{
if (enumerator == null)
throw new ArgumentNullException("enumerator");
_enumerator = enumerator;
_buffer = new List<T>();
_index = -1;
}
public bool MovePrevious()
{
if (_index <= 0)
{
return false;
}
--_index;
return true;
}
public bool MoveNext()
{
if (_index < _buffer.Count - 1)
{
++_index;
return true;
}
if (_enumerator.MoveNext())
{
_buffer.Add(_enumerator.Current);
++_index;
return true;
}
return false;
}
public T Current
{
get
{
if (_index < 0 || _index >= _buffer.Count)
throw new InvalidOperationException();
return _buffer[_index];
}
}
public void Reset()
{
_enumerator.Reset();
_buffer.Clear();
_index = -1;
}
public void Dispose()
{
_enumerator.Dispose();
}
object System.Collections.IEnumerator.Current
{
get { return Current; }
}
}
Then I would expose this kind of enumerator using an extension method:
public static class TwoWayEnumeratorHelper
{
public static ITwoWayEnumerator<T> GetTwoWayEnumerator<T>(this IEnumerable<T> source)
{
if (source == null)
throw new ArgumentNullExceptions("source");
return new TwoWayEnumerator<T>(source.GetEnumerator());
}
}
Note that this is definitely overkill if the collection you're dealing with is already an indexed collection such as a T[]
or a List<T>
. It makes more sense for scenarios such as when you're enumerating over a sequence that isn't already in a conveniently indexed form and you want to be able to go backwards as well as forwards.
The IEnumerator
(and IEnumerator<T>
) interfaces only implement a forward only enumerator. You'll need to make your own class or interface if you want to allow bi-directional iteration through your collection.
You can't go backwards with IEnumerator. Either suck the entire set into a List or cache the current element on each pass through the loop, so it's available to the next pass.
精彩评论