C #: Diferencia entre List y Collection (CA1002, No exponer listas genéricas)

Intenté ejecutar Run Code Analysis en un proyecto aquí, y obtuve una serie de advertencias que decían algo como esto:

CA1002: Microsoft.Design: cambie ‘List < SomeType >’ en ‘ SomeClass.SomeProtectedOrPublicProperty ‘ para usar Collection, ReadOnlyCollection o KeyedCollection

¿Por qué debería usar Collection lugar de List ? Cuando miro la documentación de msdn, parecen casi iguales. Después de leer la ayuda de error para la advertencia, encontré que

System.Collections.Generic.List (T) _es una colección genérica diseñada para rendimiento no herencia y, por lo tanto, no contiene ningún miembro virtual.

Pero, ¿qué significa esto realmente? ¿Y qué debería estar haciendo en su lugar?

¿Debería seguir usando List internamente, y luego en las propiedades devolver una new Collection(someList) lugar? ¿O debería simplemente comenzar a utilizar Collection lugar de List ?

En resumen, la lista genérica no tiene métodos virtuales para Agregar, Eliminar, etc., ya que fue diseñada para ser rápida, no extensible. Esto significa que no puede cambiar esta implementación concreta por una subclase útil (aunque puede crear una subclase ya que no está sellada).

Por lo tanto, al exponer la Lista, nunca puede extender su colección para rastrear agregar o eliminar operaciones (por ejemplo) sin romper el contrato público de la clase.

Al exponer su colección como IList o algo así, aún puede utilizar la Lista como el almacén de respaldo real, pero conserva la extensibilidad futura ya que puede cambiar la implementación de concerete más adelante sin cambiar el contrato público de su clase.

Collection expone algunos miembros virtuales (insertar, eliminar, establecer, borrar) que puede anular y proporcionar funcionalidad adicional (como eventos de notificación) cuando se cambia la colección.

Es posible que no lo necesite ahora, pero es un requisito común para las clases que contienen colecciones, por lo que es mejor planearlo por adelantado. Como Collection está diseñado teniendo en cuenta la extensibilidad, es muy flexible. Si en el futuro decide que necesita alguna característica adicional en la colección, puede extenderla sin ningún cambio en la interfaz pública de la clase. Si hubiera usado una lista, habría tenido que cambiarla a una colección, lo que significa que habría roto todas las llamadas de su clase porque tendrían que cambiarse a listas de uso.

List por otro lado, está diseñada teniendo en cuenta el rendimiento, por lo que solo debe usarse en casos específicos en los que el rendimiento es muy importante. Debido a que no es extensible, los cambios futuros en cualquier cosa que use una lista romperán todo lo demás que dependa de ella. Normalmente, la List solo se debe usar internamente en clases de muy bajo nivel y no debe exponerse a nada para reducir las posibilidades de futuros cambios de rotura.