Ограничить размер общей коллекции?

Есть ли способ ограничить размер общей коллекции?

У меня есть стек WriteableBitmap, который я использую для хранения клона WriteableBitmap при каждом изменении, а это означает, что я могу легко отменить, просто вытащив самый последний WriteableBitmap из стека.

Проблема заключается в использовании памяти, я хочу ограничить этот стек до 10 объектов, но я не вижу свойства, позволяющего мне легко это сделать. Есть ли способ, или мне придется проверять размер стека при каждом изменении и копировать последние 10 объектов в новый стек всякий раз, когда я нажимаю 10, и при каждом последующем изменении? Я знаю, как это сделать, но надеялся, что есть более простой способ, не так ли?


person JMK    schedule 31.12.2012    source источник
comment
Вы можете создать свою собственную коллекцию (например, получить из существующей), и вы можете переопределить метод добавления и реализовать там свою логику проверки размера...   -  person nemesv    schedule 31.12.2012


Ответы (4)


Для этого вам нужно реализовать собственную оболочку. Прямого варианта нет.

class FixedSizeStack : Stack
{
    private int MaxNumber;
    public FixedSizeStack(int Limit)
        : base()
    {
        MaxNumber = Limit;
    }

    public override void Push(object obj)
    {
        if (this.Count < MaxNumber)
            base.Push(obj);
    }

}
person Habib    schedule 31.12.2012
comment
Я думаю, что это начальная емкость, она увеличивается по мере необходимости, чего я пытаюсь избежать! - person JMK; 31.12.2012
comment
Не рекомендовал бы использовать наследование в этом случае. Этот ответ нарушает LSP, он меняет контракт для метода Push. Однако использовать композицию можно, просто нужно написать больше кода, чтобы представить элементы стека, которые должны присутствовать в FixedSizeStack. - person Palec; 02.10.2020

Чтобы уточнить ответ Тилака, вот пример кода:

  public class LimitedSizeStack<T> : LinkedList<T>
  {
    private readonly int _maxSize;
    public LimitedSizeStack(int maxSize)
    {
      _maxSize = maxSize;
    }

    public void Push(T item)
    {
      this.AddFirst(item);

      if(this.Count > _maxSize)
        this.RemoveLast();
    }

    public T Pop()
    {
      var item = this.First.Value;
      this.RemoveFirst();
      return item;
    }
  }
person Oliver    schedule 10.12.2013
comment
Не рекомендовал бы использовать наследование в этом случае. Оригинальные методы все еще существуют, и благодаря их использованию максимальный размер может быть превышен. - person Palec; 02.10.2020

Вы можете использовать LinkedList, который представляет список с двойными ссылками для имитации Круговой стек.

Вы можете AddFirst() соответствовать Push(). Если Count равно 10, вы можете использовать RemoveLast().

Для Pop() вы можете использовать RemoveFirst()

person Tilak    schedule 31.12.2012

Вам нужно будет проверить размер (я полагаю, вы получите исключение, если установите ограничение и не проверяете, заполнен ли он).

Редактировать

Вы не получите исключение, если размер был установлен, но размер просто увеличивается, поэтому вам нужно проверить размер (через http://msdn.microsoft.com/en-us/library/6335ax0f.aspx): -

Если Count уже равен емкости, емкость стека увеличивается за счет автоматического перераспределения внутреннего массива, а существующие элементы копируются в новый массив перед добавлением нового элемента.

person Ross Dargan    schedule 31.12.2012