Пример шаблона MSDN для реализации метода Dispose() показывает установку ссылки на удаленный управляемый ресурс на null (_resource = null
), но делает это вне блока if (disposing)
:
protected virtual void Dispose(bool disposing)
{
// If you need thread safety, use a lock around these
// operations, as well as in your methods that use the resource.
if (!_disposed)
{
if (disposing) {
if (_resource != null)
_resource.Dispose();
Console.WriteLine("Object disposed.");
}
// Indicate that the instance has been disposed.
_resource = null;
_disposed = true;
}
}
Не следует ли _resource = null
размещаться внутри этого кодового блока? Если выполняется вызов Dispose(false)
, тогда _resource
будет null и не сможет быть впоследствии удалён!??
Конечно, Dispose(false)
вызывается только (на практике) временем выполнения во время финализации. Но если _resource
ранее не было размещено, то в чем необходимость установить значение null в этот момент, когда объект (включая поле члена _resource
) собирается собирать мусор?
[конец оригинального вопроса]
Последующие действия:
После большого чтения появляется сообщение о том, что ссылка на null не нужна, но может быть хорошей идеей для "тяжелых" объектов-членов, если у вас есть основания полагать, что содержащий класс (тот, который находится в распоряжении) может не быть собранным мусором в ближайшее время.
Знайте, что удаление объекта не является гарантией того, что объект был "освобожден" по потребляющему коду. Упомянутый объект может храниться (в коллекции или иным образом) для различных целей или просто по ошибке. Я могу представить себе приложение, которое использует объекты из коллекции, затем избавляет от них, но сохраняет их в коллекции для последующего процесса для выполнения удаления и записи конечного состояния (или что-то в этом роде... кто знает...)
Выводы:
- Настройка ссылок на "тяжелые" объекты-члены для нулевого освобождения для сбора мусора, даже если расположенный объект не освобожден.
- Это избыток для очистки ссылок для всех объектов.
- Следовательно, размещение оператора
_resource = null
(исходный вопрос) не имеет значения по двум причинам: (A) Использование его вообще - это только о чем подумать после прочтения выше; (B) В примере MSDN он выполняется как дляDispose(true)
, так и дляDispose(false)
, но последний возникает только тогда, когда объект завершен и собирается собирать мусор в любом случае!
Таким образом, я предпочитаю разместить _resource = null
внутри самого внутреннего блока if
:
if (disposing) {
if (_resource != null) {
_resource.Dispose();
_resource = null;
}
}
Таким образом, все коды _resource
сохраняются вместе. Другие мысли, кто-нибудь?
Дополнительная информация: