Подтвердить что ты не робот

С#: должны ли переменные объектов присваиваться null?

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

4b9b3361

Ответ 1

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

Ответ 2

Чем больше IMO, вызывается Dispose на объектах, реализующих IDisposable.

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

Ответ 3

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

Ответ 4

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

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

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

Ответ 5

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

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

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

  • Это член возможно долгоживущего объекта, больше не будет использоваться этим объектом и имеет значительный размер. Здесь присвоение null - это оптимизация.
  • Это член возможно долгоживущего объекта, который больше не будет использоваться этим объектом и поэтому был бы направлен на освобождение его ресурсов. Здесь присвоение значения null является вопросом безопасности, так как легче найти случай, когда случайно используется нулевой объект, чем где случайно используется расположенный объект.

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

Ответ 6

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

Внесение лишнего нулевого присвоения в код не сильно ухудшает производительность, и это вообще не влияет на управление памятью, но добавляет немотивированные инструкции к коду, что делает его менее читаемым.

Сборщик мусора знает, когда ссылка используется в последний раз в коде, поэтому он может собирать объект, как только он больше не понадобится.

Пример:

{
  // 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;
}

Ответ 7

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

Ответ 8

Для объекта, который должен реализовать IDisposable, в качестве практики я установил для всех членов значение null в реализации IDisposable.

В далеком прошлом я обнаружил, что эта практика значительно улучшила потребление памяти и производительность приложения .NET Compact Framework, работающего на Windows Mobile. Я думаю, что .NET Compact Framework в то время, вероятно, имел очень минималистичную реализацию сборщика мусора по сравнению с основным .NET Framework, и сам процесс разделения объектов в реализации IDisposable помог GC на .NET Compact Framework сделать свое дело,

Дополнительной причиной такой практики является то, что после выполнения IDisposable для объекта фактически нежелательно, чтобы кто-либо пытался использовать какой-либо элемент на удаленном объекте. Конечно, в идеале вы бы хотели исключение ObjectDisposedException из объекта, который был удален при попытке доступа к какой-либо из его функций, но вместо этого NullReferenceException лучше, чем вообще никакого исключения. Вы хотите знать о том, как код возится с удаленными объектами, поскольку дурачиться с неуправляемыми ресурсами, которые были выпущены, - это то, что может доставить приложению много хлопот.

ПРИМЕЧАНИЕ: я определенно не защищаю реализацию IDisposable на объекте ни по какой другой причине, кроме как для установки элементов в null. Я говорю о том, когда вам нужно реализовать IDisposable по другим причинам, т.е. у вас есть члены, которые реализуют IDisposable, или ваш объект оборачивает неуправляемые ресурсы.