Pregunta

Yo uso el siguiente código para permitir myClass usar foreach. Pero soy bastante nuevo en la programación y tener alguna dificultad para comprender el siguiente código. Describí mis problemas en los comentarios. Le agradecería para proporcionar alguna información.

    public class MyClass : IEnumerable<string> 
    {  
    //1) What is IEnumerator for?
        // Whats the difference between IEnumerator and IEnumerable
    public IEnumerator<string> GetEnumerator()     
    {
             yield return "first";         
             yield return "second";     
    }      
    //2) What is it for?  It just calls above method 
   IEnumerator IEnumerable.GetEnumerator()
         {
             return GetEnumerator(); 
         } 
    }
   //3) Lastly what benefits I have from implementing genetic interface 
   //IEnumerable<string> instead of just IEnumerable
¿Fue útil?

Solución

¿Cuál es la diferencia entre IEnumerator y IEnumerable?

La respuesta de Jason es bueno, pero pensé que acababa de añadir a lo que pienso acerca de esto. Imagine que tiene una secuencia:

1, 1, 2, 3, 5, 8, 13, ...

Ahora imagina que tiene una flecha que apunta en alguna posición de esa secuencia:

1, 1, 2, 3, 5, 8, 13, ...
         ^

Una "flecha" es un objeto que puede hacer dos cosas. En primer lugar, se le puede dar lo que está apuntando. En segundo lugar, puede hacer que en sí apuntan a la siguiente cosa.

IEnumerator es una flecha. Tiene una propiedad, actual, que le da lo que está apuntando. Tiene un método, MoveNext () que se hace punto en la parte siguiente cosa.

¿Cómo se obtiene una flecha en el primer lugar? Es necesario una fábrica de flecha. Usted pregunta a la fábrica para una flecha, y le da una flecha que apunta al primer elemento de la secuencia.

IEnumerable es una fábrica de flecha. Tiene un método, GetEnumerator, que le da una flecha al primer elemento de la secuencia.

Una bonita característica de este esquema es que se pueden tener varias flechas que apuntan a diferentes lugares en la misma secuencia.

¿cuáles son los beneficios de implementar IEnumerable interfaz genérica en lugar de sólo IEnumerable?

Supongamos que la secuencia es de enteros. Si implementa IEnumerable entonces cuando se dice

foreach(int x in mysequence)

lo que realmente hacer es convertir el int en la secuencia de objeto, el boxeo el número entero y, a continuación Unbox inmediatamente la parte posterior objeto a número entero, añadiendo una asignación de memoria completamente innecesario a cada operación individual. Si el compilador sabe que la secuencia de números enteros es entonces se puede omitir la operación de boxeo innecesaria.

Supongamos que la secuencia es de cadenas. Si implementa IEnumerable<string> entonces se puede decir:

string first = mysequence.First();

Si no, entonces usted tiene que decir

string first = (string)mysequence.First();

que es innecesario y propenso a errores. En lugar de instruir al compilador a través de un reparto en el que el tipo es una cadena, puede simplemente Garantía que el tipo es cadena utilizando el sistema de tipos.

Otros consejos

1) ¿Qué es para IEnumerator? ¿Cuál es la diferencia entre IEnumerator y IEnumerable?

IEnumerator es una interfaz que representa métodos que permiten enumerar una secuencia. La diferencia entre IEnumerator y IEnumerable es que el primero representa el contrato para los objetos que le permiten enumerar una secuencia, y el segundo representa el contrato para objetos que son una secuencia que se pueden enumerar de nuevo.

public IEnumerator<string> GetEnumerator() {
         yield return "first";         
         yield return "second";     
}      


IEnumerator IEnumerable.GetEnumerator() {
    return GetEnumerator(); 
} 

2) ¿Qué es? Simplemente llama método anterior.

La primera representa una implementación del método en la GetEnumerator IEnumerable<string> contrato. Esta última representa una implementación explícita de la GetEnumerator método en la IEnumerable contrato. La cuestión es que tanto los contratos tienen un método llamado GetEnumerator pero con diferentes tipos de retorno de manera que un método no puede satisfacer simultáneamente los dos contratos (cualquier IEnumerable<T> implementación de clase también debe implementar IEnumerable como IEnumerable<T> : IEnumerable). Este último invoca la ejecución de IEnumerable<string>.GetEnumerator ya que es una aplicación sensata que devuelve un IEnumerator como IEnumerator<string> : IEnumerator.

3) Por último qué ventajas tengo de la aplicación de IEnumerable<string> interfaz genérica en lugar de sólo IEnumerable?

La tipificación estricta. Usted sabe que los elementos de una secuencia de IEnumerable<string> son todas las instancias de String mientras que usted no sabe que para IEnumerable y podría terminar tratando de echar un elemento de este último a una instancia de String cuando no puede ser.

Esta es la declaración de IEnumerable<T>:

public interface IEnumerable<out T> : IEnumerable
{
    IEnumerator<T> GetEnumerator();
}

No tienes elección, que Tienes para implementar la interfaz IEnumerable no genérico también. Usted obtendrá un error de compilación si se omite la aplicación IEnumerable.GetEnumerator (). Esto es equipaje sobrante de los días 1.x .NET donde genéricos no estaban disponibles todavía y el período de transición para .NET 2.0 donde se necesita para apoyar interoperabilidad con .NET 1.x ensamblajes. Estamos atrapados con él.

1) ¿Cuál es IEnumerator para?

IEnumerator es la parte real de trabajo con el MoveNext () y los miembros actuales.

¿Cuál es la diferencia entre IEnumerator y IEnumerable

IEnumerable es la interfaz para una colección a la señal que tiene una GetEnumerator ().

2) [GetEnumerator no genérico] ¿Qué es para? Simplemente llama método anterior

El método no genérico es allí sólo para la compatibilidad hacia atrás. Tenga en cuenta que se mueve 'a la vista' tanto como sea posible mediante el uso de la aplicación explícita. Ponerlo en práctica, ya que debe y luego olvidarse de él.

3) Por último qué ventajas tengo de la implementación de la interfaz genética IEnumerable en lugar de sólo IEnumerable

Cuando se utiliza con foreach la adavantage es pequeño, como foreach escribirá fundido a la variable de bucle. Se le permitirá utilizar var en el foreach:

foreach (var s in myClassInstance)     // needs `IEnumerable<string>` 
foreach (string s in myClassInstance)  // works with  `IEnumerable` as well 

Pero con IEnumerable<string> también tiene una interfaz de tipo seguro a otras áreas, sobre todo LINQ:

MyClass mc = new MyClass ();
string s = mc.FirstOrDefault();

GetEnumerator ha existido desde antes de los genéricos se introdujeron a la lengua, a fin de no romper el código pre-existente, las llamadas al método por defecto a través de la implementación genérica.

Con una enumeración genérica, el consumidor de la clase no tiene que emitir cada elemento de cadena cuando la iteración.

En cuanto a la tercera pregunta aquí están algunas respuestas (¿Por qué los genéricos de uso?):

debemos usar colección genérica para mejorar la seguridad y la rendimiento?

En resumen, utilizar colecciones genéricas cada vez que puede.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top