remarks cref c# fxcop

c# - cref - ¿Por qué se considera malo exponer List<T>?



remarks c# (6)

Creo que no quiere 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 per say, sino que devuelve una Lista <> en lugar de una matriz [] directamente

Esta pregunta ya tiene una respuesta aquí:

De acuerdo con FXCop, List no debe exponerse en un modelo de objetos API. ¿Por qué se considera esto una mala práctica?


Hay 2 razones principales:

  • List <T> es un tipo bastante inflado con muchos miembros no relevantes en muchos escenarios (está demasiado "ocupado" para los modelos de objetos públicos).
  • La clase no está sellada, pero no está específicamente diseñada para ser extendida (no puede anular ningún miembro)

Se considera una mala práctica si está escribiendo una API que será utilizada 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.


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 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.


Una razón es porque List no es algo que puedas 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.


Estoy de acuerdo con alce-en-la-selva aquí: List<T> es un objeto inflado sin restricciones que tiene un montón de "equipaje" en él.

Afortunadamente, la solución es simple: exponga IList<T> lugar.

Expone una interfaz de barebones que tiene la mayoría de los métodos de List<T> (con la excepción de cosas como AddRange() ) y no lo limita al tipo específico de la List<T> , que permite a los consumidores de API usa sus propios implementadores personalizados de IList<T> .

Para una mayor flexibilidad, considere exponer algunas colecciones a IEnumerable<T> , cuando corresponda.