Как работает переназначение одноразовой переменной объекта? - PullRequest
5 голосов
/ 29 сентября 2011

В C # при переназначении одноразовой переменной объекта с новым объектом, как это работает в памяти?Будет ли пространство памяти, занимаемое старым объектом, просто перезаписано новым объектом?Или мне все еще нужно позвонить Dispose(), чтобы освободить ресурсы, которые он использует?

DisposableThing thing;

thing = new DisposableThing();
//....do stuff
//thing.Dispose();
thing = new DisposableThing();

Ответы [ 3 ]

5 голосов
/ 29 сентября 2011

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

. Хороший шаблон будет следующим:

using (thing = new DisposableThing()) {
  // ... do stuff
}

thing = new DisposableThing();

В идеале, второе использование thing также должно выполняться в блоке using

3 голосов
/ 29 сентября 2011

Работает так же, как и любое другое задание: = не заботится о IDisposable и не делает магии.

Объект, изначально присвоенный переменной, должен будет Dispose вызываться вручную (или, что еще лучше, с using), как требуется. Тем не менее, не всегда может быть правильным вызвать Dispose на этом этапе: кто владеет объектом и контролирует время жизни?

Будет ли пространство памяти, занимаемое старым объектом, просто перезаписываться новым объектом?

Не применяется. Переменные «назовите» объекты. объект сам по себе , а переменная - это переменная, а не объект или «место в памяти». (См. Комментарий Эрика Липперта ниже: предыдущий - это высокоуровневое представление переменных, в то время как комментарий Эрика более точно отражает переменные в реализации C #, духе и терминологии.)

Переменные влияют только на время жизни объекта, поскольку они могут * препятствовать восстановлению объекта (и, таким образом, предотвращают [возможно, в конечном итоге] запуск финализатора). Тем не менее, переменные не управляют объектами семантическое время жизни - объект может быть удален, даже если он не подлежит восстановлению - или устраняет необходимость вызывать Dispose при необходимости.

Удачного кодирования.


При работе с одноразовыми объектами, выходящими за рамки простых областей видимости, - объектам может быть присвоено множество различных переменных в течение срока их службы! - Я считаю, что лучше всего определить, кто «берет на себя управление», что я комментирую в документации. Если время жизни объекта красиво ограничено областью действия, тогда using работает хорошо.

* Локальная переменная сама по себе необязательно достаточна для обеспечения высокой доступности объекта, так как возможно, что переменная / присваивание будет агрессивно оптимизирована, если не будет использоваться позже из той же области. Это может поражать такие объекты, как таймеры.

1 голос
/ 29 сентября 2011

Возможно и обычно существует несколько ссылок на один и тот же объект IDisposable. Нет ничего плохого в том, чтобы перезаписать или уничтожить все, кроме одной из этих ссылок, при условии, что одна ссылка будет иметь вызов Dispose до того, как она будет уничтожена.

Обратите внимание, что цель IDisposable.Dispose на самом деле состоит не в том, чтобы уничтожить объект, а в том, чтобы позволить объекту, который ранее попросил другие объекты сделать что-либо от его имени (например, зарезервировать дескриптор GDI, предоставить исключительное использование последовательный порт и т. д.), уведомите эти объекты о том, что им больше не нужно это делать. Если ничто не говорит внешним сущностям, что им больше не нужно продолжать делать что-то от имени объекта IDisposable, они будут продолжать делать это - даже если объект, для которого они это делают, больше не существует.

...