Если создается экземпляр универсальной коллекции, содержащий элементы, подлежащие удалению с идентификатором, удаляются ли эти элементы?

StackOverflow https://stackoverflow.com/questions/496722

  •  20-08-2019
  •  | 
  •  

Вопрос

Например:

Queue<System.Drawing.SolidBrush> brushQ = new Queue<System.Drawing.SolidBrush>();
...
brushQ.Clear();

Если я явно не удаляю каждый элемент из очереди и не удаляю их по отдельности, удаляются ли остальные элементы при вызове Clear()?Как насчет того, когда в очереди собирают мусор?

Предполагая, что ответ "нет", тогда какова наилучшая практика?Обязательно ли вам всегда выполнять итерацию по очереди и удалять каждый элемент?

Это может стать некрасивым, особенно если вам нужно попробовать .. наконец, вокруг каждого dispose, на случай, если кто-то выдает исключение.

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

Таким образом, похоже, что пользователь общей коллекции должен знать, что если элементы являются одноразовыми (что означает, что они, вероятно, будут использовать неуправляемые ресурсы, которые не будут очищены сборщиком мусора), то:

  1. Когда вы удаляете элемент из коллекции, убедитесь, что вы его утилизируете().
  2. НЕ ВЫЗЫВАЙТЕ Clear().Выполните итерацию по коллекции и утилизируйте каждый элемент.

Возможно, в документации для общих коллекций следует упомянуть об этом.

Это было полезно?

Решение

Когда вы ожидаете, что они будут утилизированы?Как коллекция узнает, есть ли в ней другие ссылки на объекты?

Другие советы

Универсальные коллекции на самом деле ничего не знают о типе объекта, который они содержат, поэтому вызов Clear не заставит их вызывать Dispose() для элементов.GC в конечном итоге удалит их, как только сама коллекция будет удалена, при условии, что ничто другое не имеет активной ссылки на один из этих элементов.

Если вы хотите убедиться, что объекты имеют свой метод Dispose, вызываемый при вызове Clear для коллекции, вам нужно будет создать свою собственную коллекцию, переопределить соответствующие методы и выполнить вызовы самостоятельно.

Позвольте мне посмотреть, смогу ли я написать пример кода для этого.

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

Следующий код реализует IDisposable Очередь:

class DisposableQueue<T>:Queue<T>,IDisposable where T:IDisposable

    #region IDisposable Members

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    public virtual void Dispose(bool disposing) {
        if (disposing) {
            foreach (T type in this) {
                try
                {
                    type.Dispose();
                }
                finally {/* In case of ObjectDisposedException*/}
            }
        }
    }
    #endregion
}

Как говорили другие, этого не произойдет.Однако вы могли бы создать свой собственный метод расширения, чтобы утилизировать их, если хотите.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top