objectmodel generic collection colecciones .net collections

.net - generic - ¿Cómo implementaría la interfaz IEnumerator?



system collections generic vb (5)

Tengo una clase que mapea objetos a objetos, pero a diferencia del diccionario, los mapea en ambos sentidos. Ahora estoy tratando de implementar una interfaz personalizada de IEnumerator que recorre los valores.

public class Mapper<K,T> : IEnumerable<T>, IEnumerator<T> { C5.TreeDictionary<K,T> KToTMap = new TreeDictionary<K,T>(); C5.HashDictionary<T,K> TToKMap = new HashDictionary<T,K>(); public void Add(K key, T value) { KToTMap.Add(key, value); TToKMap.Add(value, key); } public int Count { get { return KToTMap.Count; } } public K this[T obj] { get { return TToKMap[obj]; } } public T this[K obj] { get { return KToTMap[obj]; } } public IEnumerator<T> GetEnumerator() { return KToTMap.Values.GetEnumerator(); } public T Current { get { throw new NotImplementedException(); } } public void Dispose() { throw new NotImplementedException(); } object System.Collections.IEnumerator.Current { get { throw new NotImplementedException(); } } public bool MoveNext() { ; } public void Reset() { throw new NotImplementedException(); } }


Primero, no hagas que tu objeto de colección implemente IEnumerator <>. Esto lleva a errores. (Considere la situación donde dos hilos se iteran sobre la misma colección).

Implementar un enumerador correctamente resulta ser no trivial, por lo que C # 2.0 agregó soporte de lenguaje especial para hacerlo, basado en la declaración de ''rendimiento devuelto''.

La reciente serie de publicaciones de blog de Raymond Chen ("La implementación de iteradores en C # y sus consecuencias") es un buen lugar para ponerse al día.


Simplemente implemente la interfaz IEnumerable, no necesita implementar IEnumerator a menos que desee hacer algunas cosas especiales en el enumerador, que para su caso no parece ser necesario.

public class Mapper<K,T> : IEnumerable<T> { public IEnumerator<T> GetEnumerator() { return KToTMap.Values.GetEnumerator(); } }

y eso es.


CreateEnumerable() devuelve un IEnumerable que implementa GetEnumerator()

public class EasyEnumerable : IEnumerable<int> { IEnumerable<int> CreateEnumerable() { yield return 123; yield return 456; for (int i = 0; i < 6; i++) { yield return i; }//for }//method public IEnumerator<int> GetEnumerator() { return CreateEnumerable().GetEnumerator(); }//method IEnumerator IEnumerable.GetEnumerator() { return CreateEnumerable().GetEnumerator(); }//method }//class


Aquí hay un ejemplo del libro "Algorithms (4th Edition) de Robert Sedgewick".

Fue escrito en Java y básicamente lo reescribí en C #.

public class Stack<T> : IEnumerable<T> { private T[] array; public Stack(int n) { array = new T[n]; } public Stack() { array = new T[16]; } public void Push(T item) { if (Count == array.Length) { Grow(array.Length * 2); } array[Count++] = item; } public T Pop() { if (Count == array.Length/4) { Shrink(array.Length/2); } return array[--Count]; } private void Grow(int size) { var temp = array; array = new T[size]; Array.Copy(temp, array, temp.Length); } private void Shrink(int size) { Array temp = array; array = new T[size]; Array.Copy(temp,0,array,0,size); } public int Count { get; private set; } public IEnumerator<T> GetEnumerator() { return new ReverseArrayIterator(Count,array); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } // IEnumerator implementation private class ReverseArrayIterator : IEnumerator<T> { private int i; private readonly T[] array; public ReverseArrayIterator(int count,T[] array) { i = count; this.array = array; } public void Dispose() { } public bool MoveNext() { return i > 0; } public void Reset() { } public T Current { get { return array[--i]; } } object IEnumerator.Current { get { return Current; } } } }