Может ли кто-нибудь объяснить, в чем смысл обнуления объекта до того, как он выйдет из области видимости? - PullRequest
7 голосов
/ 07 марта 2011

Я видел код со следующей логикой в ​​нескольких местах:

public void func()
{
   _myDictonary["foo"] = null;
   _myDictionary.Remove("foo");
}

Какой смысл устанавливать для foo значение null в словаре перед его удалением?

Я думал, что сборка мусора заботится о количестве вещей, указывающих на то, чем изначально был * foo.Если это так, не установит ли myDictonary ["foo"] значение null просто уменьшение числа на единицу?Не произойдет ли то же самое после вызова myDictonary.Remove ("foo")?

Какой смысл _myDictonary ["foo"] = null;

edit: Чтобы уточнить - когда я сказал "удалить счетчик одним", я имел в виду следующее:
-myDictonary ["foo"] изначально указывает на объект.Это означает, что объект имеет одну или несколько вещей, ссылающихся на него.
- Как только myDictonary ["foo"] установлен в значение null, он больше не ссылается на указанный объект.Это означает, что объект имеет на одну вещь меньше ссылающихся на него.

Ответы [ 8 ]

13 голосов
/ 07 марта 2011

Нет никакого смысла.

Если вы посмотрите на то, что делает метод Remove (используя .NET Reflector), вы найдете это:

this.entries[i].value = default(TValue);

В этой строке значение элемента словаря устанавливается равным нулю, поскольку значение по умолчанию для ссылочного типа равно нулю. Таким образом, поскольку метод Remove устанавливает ссылку на null, нет смысла делать это перед вызовом метода.

4 голосов
/ 07 марта 2011

Нет особого смысла.

Однако, если метод Remove вызывает выделение кучи, и если хранимое значение велико, при вызове Remove может происходить сборка мусора, а также может собираться значение в процессе (потенциально освобождая память ). Практически, однако, люди обычно не беспокоятся о таких мелочах, как это, если только не показано , чтобы быть полезным.


Edit:

Забыл упомянуть: в идеале сам словарь должен беспокоиться о своей собственной реализации, а не о вызывающей стороне.

4 голосов
/ 07 марта 2011

Установка записи в словаре на null делает не уменьшение количества ссылок, так как null - это идеально подходящее значение для указания в словаре.

Два оператора делаюточень разные вещи.Установка значения null указывает, что это значение должно быть для этого ключа, тогда как удаление этого ключа из словаря означает, что его больше не должно быть.

1 голос
/ 07 марта 2011

В этом нет особого смысла, но бывают моменты, когда это имеет смысл.

Один из примеров - метод Dispose(). Рассмотрим этот тип:

public class Owner
{
    // snip

    private BigAllocation _bigAllocation;

    // snip

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            // free managed resources
            if (_bigAllocation != null)
            {
                _bigAllocation.Dispose();
                _bigAllocation = null;
            }
        }
    }
}

Теперь вы можете утверждать, что в этом нет необходимости, и вы были бы в основном правы. Обычно Dispose() вызывается только до разыменования Owner, и когда будет собран Owner, _bigAllocation также будет ... в конце концов.

Тем не менее:

Если для _bigAllocation указано значение NULL, он будет сразу же доступен для сбора , если на него никто не ссылается. Это может быть полезным, если Owner относится к генерации GC с более высоким номером или имеет финализатор. В противном случае, Owner должен быть выпущен до того, как _bigAllocation будет иметь право на сбор.

Хотя это своего рода угловой случай. У большинства типов не должно быть финализаторов, и в большинстве случаев _bigAllocation и Owner будут в одном поколении.

0 голосов
/ 21 апреля 2011

Это похоже на старую привычку C ++.

Я подозреваю, что автор беспокоится о старых коллекциях и / или других языках. Если память служит, некоторые коллекции в C ++ будут содержать указатели на собранные объекты, а когда «удалено» будет только удалять указатель, но не будет автоматически вызывать деструктор недавно удаленного объекта. Это вызывает очень тонкую утечку памяти. Стало привычкой устанавливать объект в null, прежде чем удалять его, чтобы убедиться, что деструктор был вызван.

0 голосов
/ 07 марта 2011

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

0 голосов
/ 07 марта 2011

Если это так, не установил бы для myDictonary ["foo"] значение null просто уменьшить счет на единицу?

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

Не вижу смысла в том, что код такой, какой он есть.

0 голосов
/ 07 марта 2011

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

...