C #: должны ли переменные объекта быть присвоены нулю? - PullRequest
43 голосов
/ 11 октября 2010

В C # необходимо ли присваивать объектную переменную null, если вы закончили ее использовать, даже если она все равно выйдет из области видимости?

Ответы [ 7 ]

38 голосов
/ 11 октября 2010

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

27 голосов
/ 11 октября 2010

Что важнее IMO, так это вызов Dispose для объектов, которые реализуют IDisposable.

Кроме того, присвоение нуля ссылочным переменным будет просто означать, что вы явно указываете конец области действия - в большинстве случаев это просторанние инструкции (например, локальные переменные в теле метода) - с эрой оптимизаций компилятора / JIT вполне возможно, что среда выполнения сделает то же самое, так что вы действительно ничего не получите от этого.В некоторых случаях, таких как статические переменные и т. Д. (Область действия которых относится к уровню приложения), вам следует присвоить переменной значение null, если вы закончили использовать ее, чтобы объект собирал мусор.

24 голосов
/ 11 октября 2010

Стоит ли выключать машину перед тем, как отправлять ее к озеру?
Нет. Это распространенная ошибка, но это не имеет значения.Вы не устанавливаете объект в ноль, а только одну ссылку на него - объект все еще находится в памяти и все еще должен собираться сборщиком мусора.

17 голосов
/ 12 октября 2012

Большинство из этих ответов имеют правильный ответ, но по неправильным причинам.

Если это локальная переменная, переменная падает в стеке в конце метода, и, следовательно, объект, на который она указывала, будет иметь на одну ссылку меньше. Если эта переменная была единственной ссылкой на объект, то этот объект доступен для GC.

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

11 голосов
/ 11 октября 2010

Присвоение нуля обычно плохая идея:

  1. Концептуально, это просто бессмысленно.
  2. Со многими переменными у вас может быть достаточно дополнительных присваиваний для нуля, чтобы вы значительно увеличили размер метода. Чем длиннее исходный код чего-либо, тем больше умственных усилий требуется для его прочтения (даже если большая его часть - просто материал, который можно отфильтровать), и тем легче обнаружить ошибку. Делайте код более подробным, чем необходимо, только если это делает его более понятным.
  3. Возможно, ваше нулевое назначение не будет оптимизировано. В этом случае возможно, что скомпилированный код не выполнит реальное освобождение, пока он фактически не достигнет этого нулевого присваивания, тогда как в большинстве случаев, когда переменная не собирается делать ничего другого, кроме выхода из области видимости (а иногда даже раньше), она может быть освобожден. Поэтому вы можете иметь очень незначительное влияние на производительность.

Единственный раз, когда я назначил бы null что-то, чтобы «очистить» переменную, которая больше не будет использоваться, а не потому, что null на самом деле является значением, которое я явно хочу назначить, это один из двух возможных случаев:

  1. Он является членом возможно долгоживущего объекта, более не будет использоваться этим объектом и имеет значительный размер. Здесь присвоение нулю является оптимизацией.
  2. Он является членом возможно долгоживущего объекта, более не будет использоваться этим объектом и поэтому был утилизирован для освобождения его ресурсов. Присвоение нулю здесь является вопросом безопасности, поскольку может быть легче найти случай, когда кто-то случайно использует нулевой объект, чем когда он случайно использует удаленный объект.

Ни один из этих случаев не применим к локальным переменным, только к членам, и оба они редки.

4 голосов
/ 11 октября 2010

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

Помещение дополнительного нулевого назначения в кодеЭто сильно не сказывается на производительности и никак не влияет на управление памятью, но добавляет немодулированные операторы в код, что делает его менее читабельным.в коде, чтобы он мог собирать объект, как только он больше не нужен.

Пример:

{
  // Create an object
  StringBuilder b = new StringBuilder();
  b.Append("asdf");
  // Here is the last use of the object:
  string x = b.ToString();
  // From this point the object can be collected whenever the GC feels like it
  // If you assign a null reference to the variable here is irrelevant
  b = null;
}
0 голосов
/ 04 июля 2011

Я просто хотел бы добавить, что AFAIK, это был только допустимый шаблон для одного выпуска Visual Basic, и даже , что было несколько спорным.(IIRC это было только для объектов DAO.)

...