Pregunta

Recientemente le pregunté a alguien por qué prefería devolver una matriz fuertemente tipada sobre una IList. Siempre pensé que programar contra una interfaz era el programa más flexible y mejor cuando se enfrentaba a un proyecto que tenía una larga vida. Así que me pareció extraño cuando él respondió:

  

Normalmente preferimos tipos inmutables   sobre mutables. Arrays son   inmutable. IList no lo es.

No estoy completamente seguro de entender esta declaración. ¿Alguien puede ayudar a aclarar esto?

Gracias por la ayuda que puedan brindar.

¿Fue útil?

Solución

Creo que tal vez pensó que debido a que la propiedad de la longitud de una matriz es inmutable, de alguna manera las matrices son más inmutables que IList o quizás usó la palabra equivocada e intercambió el concreto con inmutable. Quién sabe, pero es una respuesta extraña.

Creo que con la devolución de una Lista hay algo que implica que está bien modificarla o que puede cambiar mientras se devuelve una matriz, no implica tanto.

Por ejemplo, si tuviera un modelo de objeto en la parte superior de un repositorio y tuviera un método como GetCars () que devolviera una Lista y un programador junior viera automóviles. Agregue (Car c) ... ¿Creería que era completamente loco para pensar en autos. ¿Agregar (new Car ()) en realidad podría agregar un auto al repositorio? Las matrices son inherentemente más explícitas.

Creo que el uso de la Lista es más apropiado en propiedades, como Page.Controls.Add

Prefiero devolver matrices con más frecuencia que List por varias razones.

  • Hábito. Colecciones en 1.0 / 1.1 SUCKED

  • Prefiero que mis métodos devuelvan el más simple & amp; objeto más ligero que puedan. Si necesito hacer un Array a List es trivial.

  • Se pueden usar en .net 1.1 y reduce la superficie de refactorización. Si alguna vez necesité soportar versiones anteriores del tiempo de ejecución, puedo reutilizar al menos parte de mi código o aplicar un modelo de objeto idéntico.

Otros consejos

Quienquiera que " él " Es decir, está 100% equivocado en el tema. Las matrices son muy mutables. Esta es, de hecho, una de las razones para no devolver una matriz. No hay forma de evitar que una persona que llama cambie los elementos de una matriz a lo que quiera.

La única forma en que un Arrray es inmutable es en su longitud. Una vez que se asigna una matriz, su longitud no se puede cambiar. Incluso las API, como Array.Resize, en realidad no cambian el tamaño de la matriz, solo asignan una nueva, copian el contenido y devuelven la nueva matriz (por referencia en este caso).

Sin embargo, estoy de acuerdo en que hay muchos casos en los que es mejor devolver datos inmutables. La principal es que le permite devolver una referencia a una colección interna de una clase sin hacer una copia completa y, al mismo tiempo, evitar que la persona que llama entrometa su estado interno. La mayoría de las colecciones mutables no pueden hacer tales garantías.

Siempre prefiero una ReadOnlyCollection . Todas las ventajas de una lista, pero de solo lectura.

Un punto que podría haber querido decir es que IList incluye los métodos Insertar, Eliminar y Agregar, por lo que la propia colección se puede modificar. T [], por otro lado, no puede tener elementos agregados.

Debo agregar que FxCop recomienda devolver ReadOnlyCollection en su lugar. El indexador es de solo lectura, por lo que no puede cambiar los elementos, y los métodos Add y otros similares lanzan la excepción NotSupportedException.

En principio, tiene razón, pero no sabe cómo practicarlo correctamente ...

  

Normalmente preferimos tipos inmutables   sobre los mutables.

Eso es correcto. Los tipos inmutables son más agradables para trabajar

  

Las matrices son inmutables. IList no lo es.

Eso no es correcto. Ninguno de los dos es inmutable.

Si desea devolver una colección que sea inmutable, devuelva un IEnumerable < T > o un ReadOnlyCollection < T > (utilizando la List < T > Método .AsReadOnly ). Aún así, esos no protegen los objetos si ellos mismos no son inmutables. Aunque solo puede leer de las colecciones, aún puede cambiar los datos en cada objeto si lo permiten.

Además, debe considerar la "propiedad" de la colección que está devolviendo. Si está creando una matriz con el único propósito de devolverla, entonces no hay razón para no darle el control total. Si, por otro lado, está devolviendo una colección que es miembro de la clase, solo debe permitir el menor acceso que sea necesario.

Yo tampoco lo entiendo. Las matrices son muy mutables, excepto por su tamaño. Los elementos individuales todavía pueden ser modificados. Quizás quiso decir que las matrices son tipos de valor y las listas son tipos de referencia. No lo sé.

De todos modos, probablemente debería echar un vistazo a Opinión de Eric Lippert sobre el tema. También podría proporcionarle algo de munición para el debate.

¿Quizás esta persona no sabe de qué está hablando?

La razón para usar una Interfaz como tipo de retorno sobre el tipo real en sí, es ocultar la implementación interna del llamante. Esto permite que la implementación cambie el tipo real sin repurcusiones al resto de la aplicación.

No tiene ningún sentido copiar una colección utilizada internamente en una matriz para uso externo, por ninguna otra razón que no sea mutable o inmutable.

Los problemas separados son: - Devuelve una lista de datos fuertemente tipados o no. IList o IList. Siempre se prefiere el uso de datos fuertemente tipados. - mutable o inmutable. ICollection, IList o IEnumerator Vuelve con lo que quieras permitir a los datos. Para una lista de solo lectura, devuelva solo un IEnumerator. Si la persona que llama puede modificar la colección, utilice ICollection o IList.

Básicamente, dice "preferimos las estructuras que no se pueden cambiar fácilmente en el tiempo de ejecución, porque creemos que son menos vulnerables a los errores". Si eso es correcto en este caso es otra pregunta.

¿Quizás quiso decir el tamaño de la matriz como " inmutable " ;? Básicamente, declaras el tamaño una vez y te quedas con él. Con las listas, siempre puede utilizar " Agregar " ;.

Supongo que si está seguro sobre el tamaño de la lista, ¿quizás la matriz sea un poco más rápida?

Bueno. IList es mutable en el sentido de que puede agregar y eliminar elementos, en lugar de simplemente cambiar los elementos que ya están allí. Una matriz le permite meterse con elementos individuales, pero un índice en particular nunca será completamente inválido. Hay varias razones para preferir la inmutabilidad: por ejemplo, hace que el área de superficie para la corrupción accidental de datos sea mucho más pequeña.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top