2011-02-24 12 views
15

Duplicar posible:
C# - List<T> or IList<T>¿Por qué debería devolver IList <T> sobre la lista <T>?

está escrito todo, así que debería volver IList<T> de sus métodos y no List<T> pero no puede encontrar ninguna realmente buenas razones para ello. Sigo encontrando código que hace esto, y luego el código de llamada por lo general hace una de dos cosas:

  1. llamada new List<T>(returnedIList) por lo que se puede usar todos los métodos agradables en la Lista
  2. arroja de nuevo a List<T> para que pueda utilizar todas los métodos agradables en la Lista

el primero de ellos es torpe y el segundo tirarían (tiempo de ejecución)InvalidCastException si la implementación realidad cambió a algo más de todos modos (lo que lo hace totalmente s tupido).

si uso List<T> y por alguna razón tiene que reemplazarlo con una implementación de IList<T> que no puedo heredar de List<T> entonces voy a obtener errores de compilación y tiene que cambiar algo de código. Probablemente eso sea muy poco probable y, si sucede, no es mucho trabajo de arreglar. Seguramente no vale la pena perder los beneficios de List<T> y/o tener que lanzar/nuevo List<T> (Existe, Buscar, etc.) para recuperarlos en este escenario poco probable.

Entonces, ¿hay otras razones para devolver IList<T>?

+2

No solo está "escrito completamente", esta misma pregunta ya ha sido hecha y respondida. –

+0

Disculpas: después de 3 páginas de resultados dejé de buscar, ¡ASÍ QUE "Relevancia" parece estar un poco apagado para mí últimamente! Yendo con esta respuesta: http://stackoverflow.com/questions/400135/c-listt-or-ilistt/1522826#1522826; D –

+0

No se necesita disculpa, la búsqueda en SO es de utilidad limitada. Busqué en Google con el sitio: stackoverflow.com! para encontrar el idiota! –

Respuesta

1

La razón es que su método se puede usar con cualquier cosa que implemente IList<T>, y no solo una Lista. Empeoró aún más, desde el advenimiento de Linq, he empezado a hacer muchas cosas para devolver Enumerable<T> o incluso solo IEnumerable.

No estoy seguro de entender la dificultad, sin embargo. Si algo devuelve una lista real, y su devolución depende de eso, o si su uso es específico para eso, entonces debe devolver List<T>. De lo contrario, no debería tener que enviarlo a una lista.

+0

Sospecho que el código de llamada se escribió después del método, y el programador se mostró reacio a cambiar el método para devolver una Lista concreta, y estoy tratando de comprender si esa decisión está justificada. –

1

Realmente debería devolver IEnumerable si es posible, de lo contrario IList.

La razón es que es posible que desee usar algo más que una Lista en el futuro. No es raro implementar su propia lista que implementa IList y luego no necesita cambiar la mayor parte de su código.

Busque los tipos derivados de IList y verá que obtiene muchos éxitos solo dentro del framework .NET.

+0

IEnumerable no funciona para lo que hace gran parte de este código (y me encantaría cambiarlo, por un lado, odio cargar todo en la memoria cuando podríamos "transmitir" los resultados). Si tuviéramos que implementar una lista personalizada, me imagino que sería más probable que comenzara desde la Lista que enrollar todo el asunto? –

+0

IEnumerable es en realidad una gran manera de devolver cosas que pueden terminar siendo utilizadas como una lista, porque las Listas nuevas se pueden crear directamente desde un IEnumerable (como su primer ejemplo). No podría decirlo con certeza, pero sospecho que la sobrecarga de hacer esto, en comparación con devolver un nuevo objeto List directamente, es cero. Algo que devuelve IEnumerable debería implementarse con 'yield', por lo tanto, no crearía ningún objeto de lista nuevo. Por lo tanto, el número de instancias de una lista y agregar elementos a ella ser idéntico e a su manera. –

+0

Sí, sé que IEnumerable no se ajustará a la cuenta siempre, pero si lo hace, puede utilizar repentinamente cosas como arreglos fijos e IQuerables, lo que ayuda mucho una vez que se ha acostumbrado. No es necesario que las listas más avanzadas amplíen List, un ejemplo podría ser listas de carga diferida que tienen una estrategia de almacenamiento totalmente diferente que List, por lo que sí, la lista puede ser la base, pero normalmente no la utilizo (en ese caso, la envuelvo). en lugar). –

10

Me parece que está viendo un código de poca calidad.

Al devolver IList<T> en lugar de List<T>, permite que su código sea más flexible. Puede reemplazar la implementación con cualquier colección que implemente IList<T> sin romper ningún código de llamada. Eso es bueno ... pero solo cuando la funcionalidad definida en IList<T> coincida con sus necesidades.

Puede generalizar eso para decir que siempre debe devolver el tipo más genérico posible. En la mayoría de los casos, puede salirse con la suya con IEnumerable<T>, pero si necesita más funcionalidad, entonces IList<T> funciona. Si eso no lo corta, regrese el tipo de concreto y termine con él.

En las dos situaciones que menciona, es necesario utilizar algo no proporcionado directamente por IList<T> (y si no lo hay, ambos métodos son erróneos). En esos casos, o bien el método debe devolver List<T> para proporcionar la funcionalidad necesaria o la persona que llama debe utilizar otro método.

+0

¡Sí! Es exactamente lo que todos dicen sobre las mejores prácticas. Sin embargo, probablemente porque estoy trabajando la mayor parte del tiempo con un código que está más orientado con funciones con un nivel de abstracción más alto (como reglas comerciales), no tuve en los últimos 12 años una situación en la que tenga problemas. para cambiar la implementación. Sin embargo, puedo ver casos cuando maneja la clase que implementa la lista y desea que esta clase sea heredada por otros casos donde hay un beneficio de usar IList sobre List. – Samuel

1

La idea es dejar que la persona que llama decida qué colección usará. Ves a mucha gente que regresa IEnumerable<T> siempre que pueden. En general, se considera buena práctica hacerlo. Al volver IList, la persona que llama utiliza la implementación de IList que prefiera al devolver List. Requiere que copie manualmente los datos de la Lista en su colección de datos de su elección.

Devolución IEnumerable es ideal.

+0

No entiendo cómo el regreso de IList permite que la persona que llama decida sobre la implementación (estamos hablando de regresar, no aceptar como argumento, si eso es lo que quería decir) –

+0

Tomaré el ejemplo de IEnumerable a medida que más clases implementen interfaz. Cuando llamo a un método que devuelve un IEnumerable, puedo decidir solamente foreach() a través de él o crear una Lista/Cola/Pila/SortedList, etc. con él. Me permite usar la implementación de la interfaz IEnumerable que prefiero. Por otro lado, devolver una lista me obliga a utilizar una lista o crear una pila, por ejemplo, y a ingresar manualmente cada elemento de la lista en mi pila. –

+0

Si devuelvo List, también podría crear cualquiera de estos (¡ya que List es IEnumerable)! –

Cuestiones relacionadas