2010-01-04 20 views
8

Si un método toma un parámetro del tipo System.Collections.IList, ¿puedo pasar legítimamente/con seguridad un tipo de tipo System.Collections.Generic.IEnumerable<T>?Conversión de IEnumerable <T> a IList

Agradecería una explicación exhaustiva de por qué esto es posible y qué sucede realmente con el objeto T cuando se usa IEnumerable<T> dentro del método.

¿Se ha convertido al tipo base de objeto?

¿Se usa como System.Collections.IEnumerable?

¿Hay algún escenario donde esto cause problemas (es decir, problemas de rendimiento)?

Gracias de antemano, John

Respuesta

25

Sin, no se puede pasar una IEnumerable<T> a un método que toma IList. La interfaz IEnumerable<T> no es convertible a IList e intentar pasar una variable de tipo IEnumerable<T> a un método que toma IList dará como resultado un error de compilación.

Con el fin de hacer este trabajo tendrá que hacer una de las siguientes

  1. En lugar de tener un IEnumerable<T>, mantener una referencia a un tipo que implementa tanto IEnumerable<T> y IList. List<T> es un buen candidato aquí
  2. Convierte la instancia IEnumerable<T> a un nuevo objeto que es convertible a IList. Por ejemplo, en 3.5+ puede llamar al método de extensión .ToList() para crear un nuevo List<T> sobre la enumeración.
2

No. No puede, sin necesidad de utilizar el método ToList() extensión. Creo que esto no debería causar que es un gran problema de rendimiento; si tienes una alternativa, mide el tiempo y compara.

También podría usar new List<T>(myIEnumerable) - la documentación dice que esa función es una operación O(n), pero no puedo encontrar nada más sobre ToList(). Además, recuerde que List<T> también implementa IList así como IList<T>.

1

IEnumerable no permite el acceso indexado a la colección, mientras que IList lo hace. Por lo tanto, IList es más que IEnumerable y no podrá salirse con la suya. Por supuesto, algunas clases implementan ambas interfaces (por ejemplo, List <) y funcionarán bien.

Si necesita pasar de IEnumerable a IList, primero puede intentar un cast, si tiene suerte, funcionará. De lo contrario, tendrás que recurrir a la colección IEnumerable y crear un nuevo IList.

Editar: use ToList() en lugar de hacer alarde de usted mismo como otros han sugerido.

0

No, no puede pasarlo como un Enumerable. IList implementa IEnumerable, por lo que si pasa su método a IList, puede usarlo de manera segura como IEnumerable. VS no se compilará el siguiente:

private static void Test(IList<int> list){ } 

Test(Enumerable.Range(0, 10)); 

error devuelto:

Argument '1': cannot convert from System.Collections.Generic.IEnumerable<int>' to 'System.Collections.Generic.IList<int>' 
Cuestiones relacionadas