Обычно не имеет значения для установки значения null. Это очень редко полезно. Это иногда вредно.
Рассмотрим сначала простейший случай:
private void DoStuff()
{
var newWin = new WinWorkers_AddWorker();
newWin.WindowState = this.WindowState;
newWin.Show();
int irrelevant = 42;
this.whoCares = irrelevant * 7;
int notRelevantEither = irrelevant + 1;
this.stillDontCare = notRelevantEither * irrelevant;
}
newWin
Здесь существует только в этом методе; он создается в нем и не выходит из области действия метода, возвращая или назначая его члену с более широкой областью.
Спросите у многих людей, когда newWin
получает сбор мусора, и они скажут вам, что это произойдет после строки с this.stillDontCare
, потому что тогда newWin
выходит за рамки. Таким образом, мы могли бы немного выиграть, назначив newWin = null
сразу после его последнего использования, но, вероятно, незначительно.
Концептуально это правда, потому что мы можем добавить код, который имеет дело с newWin
в любом месте до этой точки, и newWin
есть для нас, чтобы использовать.
На самом деле, вполне вероятно, что newWin
будет иметь право на сбор сразу после .Show()
. Хотя после этого он концептуально находится в области видимости, он фактически не используется, и компилятор это знает. (Теперь с помощью «компилятора» я буду понимать весь процесс, который создает фактический текущий код, объединяющий компилятор IL и дрожание).Поскольку память, используемая самим newWin
(то есть ссылка на стек, а не объект) больше не используется, компилятор может использовать эту память для irrelevant
или что-то еще. Там, где нет ссылки на живые ссылки, объект имеет право на сбор.
Действительно, если последние несколько методов, вызываемых объектом, фактически не используют указатель this
(будь то напрямую или с помощью полей-членов), тогда объект может быть собран даже до того, как эти методы будут вызваны, поскольку они не фактически использовать объект. Если у вас был метод, указатель this
никогда не использовался (опять же, прямо или косвенно), то он никогда не может быть создан!
Теперь, имея в виду, мы можем видеть, что на самом деле не произойдет даже незначительной незначительной разницы, которая, по-видимому, возникла бы, если бы мы должны были присвоить значение null переменной до того, как переменная выпадет из объем.
Действительно, возможно, что назначение может даже потребовать больше времени, чтобы получить право на участие, потому что, если компилятор не мог видеть, что использование этой переменной не повлияет на объект (маловероятно, но, возможно, это может произойти, если есть блоки try...catch...finally
, делающие анализ более сложным), то это может даже задержать точку, в которой объект считается приемлемым. Это снова, вероятно, незначительно, но оно есть.
До сих пор так просто; хорошие вещи случаются, если мы оставляем себя в одиночестве, и оставаться в одиночестве легко.
Однако возможно, чтобы ссылка использовала значение null. Рассмотрим:
public class SomeClass
{
private WorkerThing _newWin;
private void DoStuff()
{
_newWin = new WinWorkers_AddWorker();
_newWin.WindowState = this.WindowState;
_newWin.Show();
}
}
Рассмотрим здесь, что на этот раз после того, как DoStuff()
называется, _newWin
хранится в переменной-члена. Он не будет выпадать из области действия до тех пор, пока не исчезнет экземпляр SomeClass
. Когда это произойдет?
Ну, я не могу ответить на этот вопрос, но иногда ответ важен. Если и сам SomeClass
тоже недолговечен, то кого это волнует. Он скоро выпадет из сферы, взяв с собой _newWin
. Если, однако, мы назначили _newWin = null
, тогда объект сразу будет иметь право на сбор.
Теперь некоторые важные оговорки к этому:
- В первую очередь, нет никаких оснований для
_newWin
быть переменной-члена. Если приведенный выше пример был полным кодом, мы бы переместили его обратно в локальный на DoStuff()
и получили бы не только этот эффективный способ, но и , что гораздо важнее в наших шансах на правильность, поскольку мы не можем сделать что-то глупое до _newWin
от другого участника.
- Если мы держимся за что-то в переменной-члене, это, вероятно, по уважительной причине. Эта веская причина перестанет быть фанатичной по поводу очистки переменных как можно быстрее.
- Большинство объектов просто не занимают столько памяти сами по себе. Членская переменная здесь или там не повредит.
Из-за этого основной причиной присвоения значения null переменной-члену является просто потому, что значение null стало наиболее подходящим. Назначение нулевого элемента, который больше не будет использоваться, как правило, не освобождает память ASAP, а потому, что он больше не подходит для использования, и это становится невозможным - и четко сигнализируется остальной части вашего кода как такового - когда он нулевой.
Если ссылка была более жил, чем метод (и, следовательно, положить в переменной-члена) и значительно короче долгоживущий, чем содержащего объект и потребленный очень большой объем памяти, то это просто о возможном что назначение нуля начнет иметь смысл. В крайне редких случаях, когда эта комбинация происходит, мы, вероятно, хотим присвоить ей значение null, чтобы указать, что ее больше нет для класса, так что мы по-прежнему не будем назначать нуль с целью освобождения это в GC. Это просто возможно, но на самом деле «нах».
Примечание подсчет не является реальным способом его сбора. Afaik это марка & развертки или аналогичные. – Dykam
@ Dykam правильный, и это знак и развертка. В этом отношении он может быть собран до того, как он выпадет из сферы действия. Добавить подробный ответ. –
Моно также не считается ссылкой. –