registros - longitud de un list en c#
¿Cómo anulo el método Agregar de List<T> en C#? (10)
Lea el Principio de Sustitución de Liskov , su colección es un candidato muy pobre para extender List <T>
, ni siquiera es un gran candidato para implementar IList <T>
.
¿Qué patrones de lectura se requieren en estos datos? Si solo necesita ver todas las entradas actuales, implementar el método IEnumerable <T>
y el método Agregar (T) debería ser suficiente para comenzar.
Esto puede ser implementado por una cola privada (o Deque sería mejor, pero tal colección requeriría otras API de colecciones y no sugiero que intentes implementar una tú mismo) a la que encola () durante un agregado (con Dequeue si necesario para mantener el tamaño).
Tenga en cuenta que implementar IEnumerable y proporcionar el método Agregar significa que aún puede usar la sintaxis del inicializador de Colección si es necesario.
Si necesita acceso aleatorio a los valores, la implementación de un indexador puede ser una buena idea, pero no veo qué beneficio le daría sin tener más contexto en la pregunta.
Actualmente estoy buscando hacer mi propia colección, que sería como una lista normal, excepto que solo contendría 10 elementos. Si se agrega un artículo cuando ya hay 10 elementos en la lista, entonces el primer elemento se eliminará antes de que se añada el nuevo elemento.
Lo que quiero hacer es crear una clase que amplíe System.Collections.Generic.List<T>
, y luego modifique el método Add(T item)
para incluir la funcionalidad que elimina el primer elemento si es necesario.
No puede anular Add (), no es un método virtual. Derive de IList en su lugar y use un miembro privado de Queue para la implementación.
Parece que lo mejor que puedo hacer es esto:
class MostRecentList<T> : System.Collections.Generic.List<T> {
private int capacity;
public MostRecentList(int capacity) : base() {
this.capacity = capacity;
}
public new void Add(T item) {
if (base.Count == capacity) {
base.RemoveAt(0);
}
base.Add(item);
}
}
Dado que el método add()
no está marcado como virtual.
Primero, no puede anular Agregar y aún tener polimorfismo contra List , lo que significa que si usa la palabra clave nueva y su clase se envía como una Lista, no se llamará a su nuevo método Agregar.
En segundo lugar, te sugiero que busques en la clase Queue , ya que lo que estás tratando de hacer es más una cola que una lista. La clase está optimizada para exactamente lo que quiere hacer, pero no tiene ningún tipo de limitador de tamaño.
Si realmente quieres que algo actúe como una lista pero funcione como una cola con un tamaño máximo, te sugiero que implemente IList y guardes una instancia de una cola para almacenar tus elementos.
Por ejemplo:
public class LimitedQueue<T> : IList<T>
{
public int MaxSize {get; set;}
private Queue<T> Items = new Queue<T>();
public void Add(T item)
{
Items.Enqueue(item);
if(Items.Count == MaxSize)
{
Items.Dequeue();
}
}
// I''ll let you do the rest
}
Puede echar un vistazo a la biblioteca de colecciones C5. Tienen un ArrayList <T> que implementa IList <T> y tienen un método Virtual Add. La biblioteca de colecciones C5 es una increíble colección de listas, colas, pilas, etc. Puede encontrar la biblioteca C5 aquí:
Puede extender System.Collections.ObjectModel.Collection e ignorar el método InsertItem para obtener el comportamiento que desea, y también implementa IList
Puede intentar ampliar System.Collections.ObjectModel.Collection<T>
, que es mucho más flexible. A continuación, puede anular los miembros protegidos InsertItem
y SetItem
para personalizar el comportamiento de su colección.
Simplemente puede escribir una clase que implemente IList<T>
que contenga una List<T>
interna List<T>
y escriba sus propios métodos.
Su descripción de su requerimiento suena como un Buffer Circular .
Implementé el mío, similar a esta implementación en CodePlex, excepto que la mina implementa IList<T>
.
Algunas de las otras respuestas sugieren utilizar una Queue<T>
, pero esto no es lo mismo, ya que solo permite el acceso FIFO.
Como punto general, no se recomienda derivar de List<T>
, sino que deriva de Collection<T>
e implementar cualquier material adicional que necesite. Pero para un búfer circular, probablemente sea más apropiado usar una matriz privada en lugar de derivar de Collection<T>
como la implementación de CodePlex.
También puede implementar el método de agregar a través de
public new void Add(...)
en su clase derivada para ocultar el agregado existente e introducir su funcionalidad.
Editar: contorno rugoso ...
class MyHappyList<T> : List<T>
{
public new void Add(T item)
{
if (Count > 9)
{
Remove(this[0]);
}
base.Add(item);
}
}
Solo una nota, imaginó que estaba implícito, pero siempre debe hacer referencia a su lista personalizada por el tipo real y nunca por el tipo base / interfaz ya que el método de ocultación solo está disponible para su tipo y otros tipos derivados.