Según FXCop, la lista no se debe exponer en un modelo de objetos API. ¿Por qué se considera esto una mala práctica?¿Por qué se considera malo exponer la Lista <T>?
Respuesta
Estoy de acuerdo con alce-en-la-selva aquí: List<T>
es un objeto sin restricciones, hinchado que tiene un montón de "equipaje" en el mismo.
Afortunadamente, la solución es simple: exponer IList<T>
en su lugar.
Se expone una interfaz de barebones que la mayoría tiene todos los métodos List<T>
's (con la excepción de cosas como AddRange()
) y no te limitan al tipo específico List<T>
, que permite a sus consumidores de API para utilizar sus propias costumbres implementadores de IList<T>
.
Para una mayor flexibilidad, considere exponer algunas colecciones al IEnumerable<T>
, cuando corresponda.
¿Qué recomendarías para un servicio web (donde un método no puede devolver/tomar una interfaz)? – kpollock
kpollock: lamentablemente los servicios web SOAP * convertirán cualquier IList
El hecho de que utilice IList
Creo que no desea que sus consumidores agreguen nuevos elementos a su declaración. Una API debe ser clara y completa, y si devuelve una matriz, debe devolver la estructura de datos exacta. No creo que tenga nada que ver con T por decir, pero en lugar de regresar de una lista <> lugar de una matriz [] directamente
-1. En particular, [las propiedades no deberían devolver matrices] (http://msdn.microsoft.com/en-us/library/0fss9skc%28v=VS.100%29.aspx). Mientras que los métodos pueden, en colecciones generales, secuencias enumerables e interfaces son más idiomáticas para C#. – TrueWill
Existen las 2 razones principales:
- Lista <T> es un lugar tipo hinchado con muchos miembros no relevantes en muchos escenarios (está demasiado "ocupado" para los modelos de objetos públicos).
- La clase no está sellado, pero no específicamente diseñado para ser extendida (no se puede anular cualquier miembro)
Exactamente a la derecha.Aquí hay un enlace a Krzysztof Cwalina sobre el tema: http://blogs.msdn.com/kcwalina/archive/2005/09/26/474010.aspx –
Sólo se considera una mala práctica si está escribiendo una API que será utilizado por miles o millones de desarrolladores.
Las directrices de diseño de .NET framework están destinadas a las API públicas de Microsoft.
Si tiene una API que no está siendo utilizada por muchas personas, debe ignorar la advertencia.
Ya sabes ... Estaba simplemente equivocado allí ... Actualizo mi respuesta. –
Bueno ... entonces eliminaré mi comentario, que ya no es relevante. :) –
Si bien es cierto que algunas de las reglas de FxCop son directrices de diseño del marco y pueden no ser apropiadas para algunos proyectos, incluso las bibliotecas diseñadas para equipos pequeños pueden beneficiarse de su seguimiento. ¿Alguna vez le ha dicho a 5 desarrolladores que tendrán que cambiar sus proyectos porque necesita hacer un cambio decisivo en una biblioteca (por ejemplo, observar los cambios como se menciona en @Kaagle)? ¿Alguna vez los desarrolladores de tu equipo han hecho algo que no esperabas, como modificar los contenidos de una propiedad de la lista que pretendías que fuera de solo lectura? – TrueWill
Una razón es porque List no es algo que pueda simular. Incluso en bibliotecas menos populares, he visto iteraciones que solían exponer un objeto List como IList debido a esta recomendación, y en versiones posteriores decidí no almacenar los datos en una lista (tal vez en una base de datos). Debido a que era un IList, no fue un cambio radical cambiar la implementación debajo de los clientes y aun así mantener a todos trabajando.
Una de las razones es que el usuario podrá cambiar la lista y el propietario de la lista no lo sabrá, mientras que en algunos casos debe hacer algunas cosas después de agregar/eliminar elementos a/de la lista. Incluso si no se requiere ahora, puede convertirse en un requisito en el futuro. Por lo tanto, es mejor agregar el método AddXXX/RemoveXXX al propietario de la clase y exponer la lista an IEnumerable o (lo cual es mejor en mi opinión) exponerlo como IList y usar ObservableCollection de WindowsBase.
Exponer 'List
- 1. ¿Por qué se considera que un "tipo inestable" es malo
- 2. ¿Por qué el ORM se considera bueno pero el "seleccionar *" se considera malo?
- 3. ¿Por qué es malo?
- 4. ¿Por qué es malo agregar a una lista?
- 5. ¿Cuál es la razón por la cual el diseño de la tabla en el código se considera malo?
- 6. ¿Por qué es "import *" malo?
- 7. (¿por qué) se considera dañino el selector de estrella CSS?
- 8. ¿Por qué esta matriz de Java se considera bidimensional?
- 9. Por qué se considera que HTTP/SOAP es "grueso"
- 10. ¿Por qué este certificado X.509 no se considera válido?
- 11. ¿Por qué asignar o inicializar NSDateFormatter se considera "costoso"?
- 12. ¿Por qué se considera sizeof a un operador?
- 13. Rcov: ¿Por qué este código no se considera cubierto?
- 14. por qué utilizar Conde con IQueryable se considera inviable
- 15. ¿Por qué javascript: void (0) se considera dañino?
- 16. ¿Por qué es JFormattedTextField malo?
- 17. ¿Por qué la co-varianza de array se considera tan horrible?
- 18. ¿Se considera `qrefresh` dañino?
- 19. ¿Por qué el transformador de mónada ListT se considera defectuoso? ¿Qué leyes de mónada se rompen?
- 20. Por qué son try-catch en main() malo?
- 21. ¿Por qué el bloqueo (esto) {...} es malo?
- 22. Bloquear en un objeto mutable: ¿por qué se considera una mala práctica?
- 23. La mejor manera de usar la Lista <T> y exponer la Colección <T>
- 24. ¿Cómo puedo convertir la lista <string> en la lista <myEnumType>?
- 25. ¿Por qué añadir un nuevo valor a la lista <> sobrescribir los valores anteriores en la lista <>
- 26. ¿Por qué la Lista <Number> no es un subtipo de la Lista <Object>?
- 27. ¿Por qué es REGISTER_GLOBALS tan malo?
- 28. ¿Por qué es la lista <T> .IndexOf() mucho más rápida que la lista <T> .Contains()?
- 29. ¿Por qué try {...} finalmente {...} es bueno; prueba {...} catch {} ¿malo?
- 30. ¿Por qué GLUT es tan malo?
Formulé la pregunta el 23 de diciembre de 2008. La pregunta a la que se vinculó fue publicada el 30 de diciembre de 2008. Diría que la mía fue lo primero. –