2010-12-10 16 views
6

Cuando implemente IList<T>, encuentro que estoy obligado a definir dos métodosGetEnumerator. Uno devuelve un valor que es del tipo IEnumerator, mientras que el otro devuelve IEnumerator<T>.¿Por qué la implementación de 'IList <T>' requiere la definición de dos métodos 'GetEnumerator'?

Estoy un poco confundido acerca de la diferencia entre estos dos métodos GetEnumerator. Si bien los tipos de devolución son obviamente diferentes, ¿no tienen esencialmente los mismos datos?

Además, ¿por qué ambas versiones de GetEnumerator pueden existir como métodos cuando difieren solo por tipo de devolución? Esto parece violar la regla en C# que especifica que los métodos sobrecargados no pueden diferir solo por tipo de devolución.

Respuesta

8

Ambos deberían devolver los mismos datos, sí.

IEnumerator es de .Net v1.1, antes de que se introdujera la tipificación genérica. IEnumerator<T> es la versión genéricamente tipada agregada en .Net v2.

La versión "anterior", IEnumerator, se ha mantenido para compatibilidad, por lo que ahora IList<T> implementa ambos.

La diferencia entre los dos es que el IEnumerator no genérico devuelve el objeto, mientras que el IEnumerator<T> genérico devuelve los T's. Aunque, el compilador de C# insertará un molde para hacer que el IEnumerator no genérico parezca fuertemente tipado cuando se usa en un foreach.

La presencia de un argumento de tipo genérico es suficiente para que el compilador diferencie entre las dos interfaces, pero para que una clase lo implemente, ambas deben implementarse explícitamente.

+1

No del todo cierto, el argumento genérico no es suficiente: uno se implementa explícitamente, el otro no. –

+1

Difícilmente podría llamar el uso no genérico de IEnumerator en una magia de bucle foreach. Simplemente intenta lanzar desde el objeto al tipo que especifique. Si falla, obtendrás una excepción. –

+0

Aceptado para explicar el problema de compatibilidad hacia atrás. Gracias. – MyNameIsJob

7

Los dos vienen de interfaces separadas que sí IList implementa, por lo que hay que poner en práctica tanto:

public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable 

Y los dos son capaces de existir debido a Explicit Interface Implementation.

+0

Gracias por ese enlace. Eso ayudó más que nada. – MyNameIsJob

3

Sí, ambos métodos deben devolver los mismos datos.

Pueden coexistir porque son parte de dos interfaces diferentes, IEnumerable y IEnumerable<T>.

0

IList<T> Implementa ambos IEnumerable<T> y IEnumerable. Las diferentes implementaciones de GetEnumerator provienen de cada una de estas interfaces. Ambos deberían devolver los mismos datos.

1

Ambos pueden existir porque uno de ellos se implementarán explicitly:

IEnumerator IEnumerable.GetEnumerator() 
{ 

} 

Si intenta hacer que los dos implícitamente definido, obtendrá errores de compilación.

Sí, deberían devolver los mismos datos.

Usted está obligado a definir las dos versiones de GetEnumerator con el fin de satisfacer ambas interfaces (IEnumerable y IEnumerable<T>) del que se deriva IList<T>. En la práctica, sin embargo, tiende a encontrar que la versión no genérica de GetEnumerator simplemente llama a la genérica en la mayoría de las implementaciones.

0

IEnumerator enumera los objetos, mientras que IEnumerator enumera T. Para su segunda pregunta, la segunda función es completo:

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 

    } 

vs

public IEnumerator<T> GetEnumerator() 
    { 

    } 
Cuestiones relacionadas