2009-08-05 20 views
90

trató de correr el análisis de código de ejecución en un proyecto aquí, y tiene un número de señales de advertencia que dice algo como esto:C#: Diferencia entre la lista <T> y Colección <T> (CA1002, no exponga las listas genéricas)

CA1002: Microsoft.Design: Cambio 'Lista < SomeType>' en 'SomeClass.SomeProtectedOrPublicProperty' Colección de usar, ReadOnlyCollection o KeyedCollection

Wh ¿Debo usar Collection<T> en lugar de List<T>? Cuando miro la documentación de msdn, parecen casi iguales. Después de leer la ayuda de error para el aviso, me encontré con que

System.Collections.Generic.List (T) _is una colección genérica, creada para un rendimiento no la herencia y, por lo tanto, no contiene ningún miembro virtuales.

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

¿Debo seguir usando List<T> internamente, y luego en las propiedades devuelvo un new Collection<T>(someList) en su lugar? ¿O debería simplemente comenzar a usar Collection<T> en lugar de List<T>?

+2

Ver [esta publicación del blog] (http://blogs.msdn.com/fxcop/archive/2006/04/27/585476.aspx) para una explicación detallada –

+1

Por cierto, si quieres saber por qué colección se encuentra en [System.Collections.ObjectModel entonces lee este] (http://blogs.msdn.com/kcwalina/archive/2005/03/15/396086 .aspx) por Krzysztof Cwalina. –

Respuesta

127

En resumen, la lista genérica no tiene métodos virtuales para Agregar, Eliminar etc., ya que fue diseñado para ser rápido, 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í, puede seguir utilizando la lista como el almacén de respaldo real, pero conservará la extensibilidad futura ya que puede cambiar la implementación de concerete más tarde sin cambiar el contrato público de su clase.

+3

¡Buena respuesta! Totalmente tiene sentido ahora: D – Svish

+5

Lo digo, '' Colección utiliza un '' Lista instancia internamente. –

20

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.

Puede que no necesite esto ahora, pero es un requisito común para las clases que contienen colecciones, por lo que es mejor planificarlo con anticipación. Debido a que 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ñado teniendo en cuenta el rendimiento, por lo que solo debe utilizarse en casos específicos donde 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, List solo debe usarse internamente en clases de muy bajo nivel y no debe exponerse a nada para reducir las posibilidades de futuros cambios de rotura.

Cuestiones relacionadas