Когда я должен реализовать IDisposable? [дубликат]

Этот вопрос уже имеет ответ здесь:

Какова лучшая практика для того, когда реализовать IDisposable?

Лучшее эмпирическое правило состоит в том, чтобы реализовать его, если у Вас есть один управляемый объект в классе, или это зависит, если объект был создан в классе или просто передан в? Я должен также сделать это для классов без управляемых объектов вообще?

37
задан Ian Nelson 12 March 2010 в 09:08
поделиться

6 ответов

Если вы имеете в виду неуправляемые объекты, тогда да, вы должны реализовывать его всякий раз, когда у вас есть один или несколько неуправляемых ресурсов, которые вы обрабатываете в своем классе. Вы также должны использовать шаблон, когда вы, возможно, держитесь за объекты, которые сами являются IDisposable, и обязательно избавляйтесь от них при удалении вашего класса.

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

29
ответ дан 27 November 2019 в 04:46
поделиться

Вы должны реализовать IDisposable, когда ваш класс содержит ресурсы, которые вы хотите освободить, когда закончите их использовать.

6
ответ дан 27 November 2019 в 04:46
поделиться

Если у него есть свойства, которые также необходимо удалить.

0
ответ дан 27 November 2019 в 04:46
поделиться

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

В качестве примера у меня есть служба, которая внедряется в дочернее представление, это дочернее представление будет подписываться на различные события типа завершения async в службе. Владелец этого дочернего представления понятия не имеет, что это за конкретный тип, он просто имеет его как интерфейс. Служба может выйти из области видимости в какой-то произвольный момент в будущем, и я не хочу, чтобы она зависала без сборки GC. Избавившись от этого дочернего представления, владелец вызовет для него Dispose, чтобы дать ему возможность отцепить любые обработчики событий. Вот немного надуманный (и очень псевдокод) пример, обратите внимание, как интерфейс для дочернего представления также реализует IDisposable .

public class OwnerView {

    public OwnerView() {
        _childView = new ChildView(myServiceReference);
    }

    public void CloseChildView() {
        if (childView != null) {
            _childView.Close();
            _childView.Dispose();
        }

        _childView = null;
    }

    private IChildView _childView;
}

public class ChildView : IChildView {

    public ChildView(MyService serviceRef) {
        _serviceRef = serviceRef;
        _serviceRef.GetSettingsAsyncFinished += new EventHandler(someEventHandler);
    }

    public void IDisposable.Dispose() {
        _serviceRef -= someEventHandler;
    }

    private MyService _serviceRef;
}

public interface IChildView : IDisposable {
    void DoSomething();
    ... etc ...
}

Есть гораздо более авторитетные комментарии по этому поводу от других участников SO, например Останавливают ли обработчики событий сборку мусора? и Сборка мусора при использовании анонимных делегатов для обработки событий . Вы также можете прочитать эту статью codeproject .

12
ответ дан 27 November 2019 в 04:46
поделиться

Когда ваш класс содержит неуправляемые объекты, ресурсы, открытые файлы или объекты базы данных, вам необходимо реализовать IDisposable .

6
ответ дан 27 November 2019 в 04:46
поделиться

Я думаю, в документации довольно ясно сказано, для чего нужен IDisposable.

Основное использование этого интерфейса - это для освобождения неуправляемых ресурсов. сборщик мусора автоматически автоматически освобождает память, выделенную для управляемому объекту, когда этот объект больше не больше не используется. Однако невозможно невозможно предсказать, когда произойдет сборка мусора. Более того, сборщик мусора не знает о неуправляемых ресурсах, таких как окна или открытые файлы и потоки.

Здесь даже есть пример. В этом примере класс, реализующий IDisposable, содержит хэндл. Ручку необходимо освободить, когда она больше не используется. Это делается в методе Dispose(). Поэтому пользователь этого класса видит, что он реализует IDisposable и знает, что класс должен быть явно утилизирован, когда он больше не нужен (так что хэндл может быть освобожден). Это лучшая практика (т.е. правило), что вы всегда должны вызывать Dispose() на IDisosable экземплярах, когда экземпляр больше не нужен.

6
ответ дан 27 November 2019 в 04:46
поделиться