polimorfism method c# design collections public-method

method - protection level c#



Colección personalizada vs Colección genérica para métodos públicos (6)

En general, es mejor exponer una de las interfaces, como IEnumerable<T> , ICollection<T> o IList<T> lugar de una clase concreta.

Esto le proporciona mucha más flexibilidad en términos de cambiar su API interna. IEnumerable<T> , en particular, le permite modificar potencialmente su interior más tarde para permitir la transmisión de resultados, por lo que es el más flexible.

Si conoce los patrones de uso esperados de sus "colecciones", debe exponer la API adecuada que le ofrezca las menores restricciones en el futuro. Si, por ejemplo, sabe que las personas solo necesitan repetir sus resultados, exponga IEnumerable<T> , de modo que puede cambiar a CUALQUIER colección más adelante, o incluso cambiar a simplemente usar rendimiento devuelto directamente.

¿Cuáles son las recomendaciones para exponer una colección personalizada frente a una genérica? p.ej

public class ImageCollection : Collection<Image> { ... } public class Product { public ImageCollection {get; set;} }

VS

public class Product { public Collection<Image> Images{get; set;} }

¿En qué casos considerarías crear una colección personalizada? ¿Cuáles son los pros y los contras de cada método?


La única razón para usar Collection<T> es si desea conectar el conjunto de métodos virtuales que le permite ver todas las mutaciones de la lista subyacente. Esto le permite realizar operaciones como responder a las eliminaciones, implementar eventos, etc.

Si no está interesado en responder o mirar estas modificaciones de recopilación, entonces una List<T> es un tipo más apropiado.


La razón principal por la que puedo pensar es que es posible que desee tener algunos métodos específicos para una colección de imágenes que operan en esa colección en sí. Entonces usaría una clase ImageCollection para contener esos métodos. Encapsulación clásica

Además, solo un lado, realmente debería exponer un getter para esa colección e inicializar un campo de respaldo de solo lectura con la colección actual. Probablemente desee que las personas agreguen / eliminen elementos a la colección, no que reemplacen todo:

class Product { private readonly Collection<Image> _images; public Product() { _images = new Collection<Image>(); } public Collection<Image> Images { get { return _images; } } }

-Oisin


Prefiero tener una propiedad genérica pública para hacer las partes internas extensibles, pero un campo privado sería el personalizado con la funcionalidad real.

Por lo general, se ve así:

public interface IProduct { ICollection<Image> Images { get; } } public class Product : IProduct { private class ImageCollection : Collection<Image> { // override InsertItem, RemoveItem, etc. } private readonly ImageCollection _images; public ICollection<Image> Images { get { return _images; } } }

También a menudo hago anidada la clase de colección personalizada dentro de una clase diferente, lo que me permite modificar algunos miembros privados de la clase padre durante add / remove.


Si está creando una API pública, considere usar una colección personalizada para las siguientes ventajas.

  • Extensibilidad: puede agregar funciones a su colección personalizada en el futuro sin cambiar la API.

  • Compatibilidad con versiones anteriores: puede cambiar las partes internas de su clase de colección a su gusto, sin romper el código existente que los clientes han programado para la colección.

  • También es más fácil hacer cambios potencialmente disruptivos con menos impacto. Tal vez más tarde decidas que no quieres que sea una Collection<Image> , sino un tipo de colección diferente: puedes adaptar tu clase de ImageCollection para tener los mismos métodos que antes, pero heredar de algo diferente, y el código del cliente no será es probable que se rompa.

Si solo es para código de uso interno, la decisión no es necesariamente tan importante, y usted puede optar por "más simple es mejor".

Un ejemplo fuera de lo común son las API de ArcGIS Server de ESRI: usan colecciones personalizadas en sus API. También usamos colecciones personalizadas en nuestra API principalmente por estos motivos.


Yo iría por el segundo. El código de cliente debe saber el tipo de imagen de todos modos.

El primero solo significa más código.