Есть ли любой смысл установить пользовательский объект на null
(Nothing
в VB.NET) в Dispose()
метод? Это могло предотвратить утечки памяти, или это бесполезно?!
Давайте рассмотрим два примера:
public class Foo : IDisposable
{
private Bar bar; // standard custom .NET object
public Foo(Bar bar) {
this.bar = bar;
}
public void Dispose() {
bar = null; // any sense?
}
}
public class Foo : RichTextBox
{
// this could be also: GDI+, TCP socket, SQl Connection, other "heavy" object
private Bitmap backImage;
public Foo(Bitmap backImage) {
this.backImage = backImage;
}
protected override void Dispose(bool disposing) {
if (disposing) {
backImage = null; // any sense?
}
}
}
Цель Dispose ()
- разрешить очистку ресурсов, которые не обрабатываются сборщиком мусора. Об объектах заботится сборщик мусора, поэтому в обычных обстоятельствах нет необходимости устанавливать ссылку на null.
Исключение составляют случаи, когда вы ожидаете, что вызывающий абонент вызовет Dispose
и удерживает экземпляр после этого. В этом случае может быть хорошей идеей установить для внутренней ссылки значение null. Однако одноразовые экземпляры обычно утилизируются и выпускаются одновременно. В этих случаях это не будет иметь большого значения.
Это может иметь смысл, если вы хотите каким-то образом предотвратить повторное использование удаленного принадлежащего экземпляра.
Когда вы устанавливаете ссылки на одноразовые поля равными нулю, вы гарантированно больше не будете использовать экземпляры.
Вы не получите ObjectDisposedException
или любое другое недопустимое состояние, вызванное использованием принадлежащего удаленного экземпляра (вы можете получить NullReferenceException
, если не проверяете наличие нулей).
Это может не иметь для вас смысла, если все IDisposable
объекты имеют свойство IsDisposed
и / или генерируют ObjectDisposedException
, если они используются после того, как они были disposed - некоторые могут нарушить этот принцип, и установка их на null может предотвратить возникновение нежелательных эффектов.
Лично я склонен; по двум причинам:
Foo
(возможно, из события), любые нижестоящие объекты (в данном случае Bitmap
) все еще могут быть собраны (в какой-то момент в будущем - когда GC захочет); вполне вероятно , что это всего лишь поверхностная оболочка неуправляемого ресурса, но каждая мелочь помогает.
IDisposable
- удобный переключатель «почти убивает» - почему бы не отсоединить все доступное? ObjectDisposedException
, если это null
Это просто бесполезно. Я считаю, что установка значения NULL в старые времена COM / VB уменьшила бы количество ссылок.
Это не относится к .NET. Когда вы устанавливаете bar на null, вы ничего не разрушаете и не освобождаете. Вы просто меняете ссылку, на которую указывает полоса, с вашего объекта на «null».Ваш объект все еще существует (хотя теперь, поскольку на него ничего не ссылается, он в конечном итоге будет собран мусором). За некоторыми исключениями и в большинстве случаев это то же самое, что произошло бы, если бы вы просто изначально не сделали Foo IDisposable.
Основная цель IDisposable - позволить вам освободить неуправляемых ресурсов, таких как сокеты TCP, соединения SQL или что-то еще. Обычно это делается путем вызова любой функции очистки, предоставляемой неуправляемым ресурсом, а не путем установки ссылки на «null».
Цель dispose ()
- очистить неуправляемые ресурсы. Соединения TCP, соединения с базой данных и другие объекты базы данных, а также множество таких неуправляемых ресурсов должны быть освобождены разработчиком в методе удаления. Так что это действительно имеет смысл.
Если вы посмотрите на узоры проектирования, почти все они могут быть избыточными. Но то, что образец означает широко используемый подход к решению подобного типа проблем. Образец конструкции обеспечивает подход или решение на уровне конструкции для набора аналогичных типов задач конструкции. Использование образца конструкции помогает решить проблему и, следовательно, быстрее ее решить.
-121--688816-Для запроса XML-файла можно использовать E4X или XPath . Я бы рекомендовал использовать новую технологию E4X, так как она более проста в использовании, чем XPath.
jQuery предлагает только стандартные иерархические функции для анализа XML-файлов ( см. здесь ), так как это не его цель делать иначе.
-121--3959356-В C # установка для объекта значения null означает освобождение ссылки на объект.
Таким образом, теоретически лучше деблокировать ссылку на управляемые объекты в методе Dispose-Method в C #, но только для возможности GC собрать объект, на который имеется ссылка, до сбора удаляемого объекта. Поскольку оба объекта, скорее всего, будут собраны в одном и том же прогоне, GC будет наиболее успешно распознавать, что на объект, на который имеется ссылка, ссылается только удаляемый тип, так что оба объекта могут быть собраны.
Также необходимость выпуска ссылки очень мала, так как все публичные члены вашего одноразового класса должны бросить исключение, если класс уже ликвидирован. Таким образом, после удаления метода, на который ссылается ссылка, доступ к объекту не будет успешным.
В VB.NET есть смысл установить в Nothing
объявленные Private WithEvents
объекты.
Обработчики, использующие ключевое слово Handles
, будут удалены таким образом из этих объектов.