2010-06-15 10 views
10

Do not expose generic listscódigo de Visual Studio Regla Análisis - "No exponga listas genéricas"

si todos mis métodos, tienen que exponer una colección, entonces necesito usuario la extensión .ToList LINQ(), en casi todas partes que necesito usar listas, o colecciones de usuarios en todo mi código.

Si ese es el caso, .ToList() está ignorando la regla ¿verdad? ¿O existe una técnica como copiar la lista o algo para arreglar la violación y aún así devolver una lista?

Respuesta

8

Deshabilito esta regla porque no creo que sea válida. Si desea devolver una colección que contiene un recuento O(1) y no es una referencia directa a un campo interno, List<T> es la mejor opción.

No entiendo muy bien su caso aquí, pero parece que tiene un método que devuelve una consulta LINQ sobre algunos datos internos. Si ese es el caso, usar un .ToList() en los datos es apropiado ya que probablemente no desee que las modificaciones futuras de sus campos internos afecten el valor de retorno de un método. En ese caso, no hay razón para no exponerlo como List<T>.

+0

reglas de bloqueo se como hacer trampa sin ? ... las reglas existen por una razón. – Fraga

+1

@Fraga, No, no es hacer trampa y a menudo desactivo ciertas reglas por diversos motivos. No son verdades universales y con frecuencia se interponen en el camino del diseño de bibliotecas de calidad. – JaredPar

+4

Son más como "pautas" de todos modos. –

3

Recuerde que todas estas reglas fueron escritas para desarrolladores de frameworks. Es probable que muchos de ellos no sean aptos, a menos que también esté escribiendo un marco.

Tendrá que hacer una llamada de juicio para cada regla para ver si es válida para sus circunstancias. Me gusta usar el análisis ya que a veces encuentra algunos errores, pero siempre termino deshabilitando ciertas reglas (por ejemplo, con bastante frecuencia tengo un catch Exception como último recurso porque necesito registrar todo tipo de errores incluso si no pueden ser manejados).

8

Esta regla puede ser realmente ruidosa, pero hay algunas razones muy válidas para evitar List<T> en el código de la biblioteca. Todo depende del contexto. Aquí hay algunas cosas a considerar antes de deshabilitar la regla o la supresión de un suceso determinado:

  • List<T> es a menudo una mala elección para los parámetros de entrada ya que obliga a las personas que llaman para copiar datos de forma innecesaria. He visto muchos códigos que declaran parámetros como List<T> o T[] cuando IEnumerable<T> sería suficiente.

  • List<T> puede ser una opción pobre para las propiedades también. Considere las siguientes alternativas:

    public class Course { 
        public List<Course> Prerequisites { get; } 
    } 
    public class Course { 
        public Collection<Course> Prerequisites { get; } 
    } 
    

    La intención es que la persona que llama puede cambiar los requisitos previos de un curso modificando la colección. En ese caso, si usamos List<Course>, no hay forma de que se notifique la clase Course cuando cambian los requisitos previos ya que List<T> no proporciona ninguna devolución de llamada de modificación. Como tal, usar List<T> en este contexto es como tener arbitrariamente muchos campos públicos. Por otro lado, podemos subclase Collection<T> y anular sus virtuales para recibir notificaciones de cambios.

List<T> funciona mejor como un valor de retorno cuando la propiedad completa de la colección se transfiere a la persona que llama. Esta es la razón por la cual Enumerable.ToList() es realmente perfectamente razonable y no viola el espíritu de la regla.

Ahora que lo pienso, lo que permite List<T> como un valor de retorno de métodos, pero continuando con la bandera List<T> propiedades y los parámetros, probablemente mejorará en gran medida la señal de la regla a ruido ...

+1

Si 'Course' simplemente quiere recibir una notificación cuando cambian los requisitos previos, entonces' BindingList 'sería una buena opción.Tiene eventos a los que puede suscribirse, en lugar de tener que derivar una nueva clase como con 'Colección ' –

+1

@Ben Voigt Indeed. También hay 'ObservableCollection '. Mi punto no era que 'Collection ' es necesariamente la mejor opción, solo que 'List ' es una opción pobre en este contexto. –

Cuestiones relacionadas