Что будет с типом var, когда закончится блок кода? - PullRequest
1 голос
/ 12 июля 2011

В чем разница между этими двумя примерами кода?

  public Test(int x)
  {
        List<int> list= new List<int>();
        List<int> list1 = new List<int>();

        list= CreateList(x);
        list1 = CreateList(x + 1);

        DoStuff(list, list1);

        list.Clear();
        list = null;
        list1.Clear();
        list1 = null;
    } 

Это способ кодирования?

    public Test(int nCount)
    {
        var list = CreateList(nCount);
        var list1 = CreateList(nCount + 1);

        DoStuff(list, list1);
    }

Ответы [ 4 ]

3 голосов
/ 12 июля 2011

Вы на самом деле не сравниваете подобное с like, поскольку все var означает «пусть компилятор решает, какой это тип».Он скомпилируется с тем же кодом (при условии, что CreateList возвращает List<int>).Таким образом, хотя ваш код функционально идентичен, вы выполняете дополнительную работу в первом примере, которую вы не реплицируете во втором.

В первом случае вы создаете списки без необходимости в качестве акта возвращения списка изCreateList(x) перезапишет то, что вы только что создали.Более точный вопрос будет задавать эту разницу между:

public Test(int x)
{
    List<int> list= CreateList(x);
    List<int> list1 = CreateList(x + 1);

    DoStuff(list, list1);

    list.Clear();
    list = null;
    list1.Clear();
    list1 = null;
}

и

public Test(int nCount)
{
    var list = CreateList(nCount);
    var list1 = CreateList(nCount + 1);

    DoStuff(list, list1);
}

В обоих случаях, когда списки выходят за рамки, они будут помечены как подходящие для мусораколлекция.Вам не нужны вызовы Clear() или для установки переменных на null.

2 голосов
/ 12 июля 2011

Ничего.

Для удобства чтения и, следовательно, в будущем для обслуживания, используйте второй. Понятно, что это намного легче понять, и из-за дизайна C # и CLR большая часть кода в вашем первом примере не требуется.

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

Подумайте о том, чтобы больше сосредоточиться на концепции объектов одноразовых , и не беспокойтесь об аспектах использования памяти / сбора мусора. Очистка списка или установка ссылки на список в null на самом деле не освобождает память; память по-прежнему выделяется до тех пор, пока сборщик мусора не восстановит ее в неопределенное время в будущем.

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

Кроме того, использование var или явное указание типа не имеет никакого значения.

0 голосов
/ 12 июля 2011

Это зависит от того, что вы делаете с «DoStuff». Если вы создадите другую ссылку на список, сборщик мусора не очистит их во втором примере. Таким образом, первый пример гарантирует, что списки очищены, а во втором он зависит от «DoStuff».

Я бы использовал следующий код:

DoStuff(CreateList(nCount), CreateList(nCount + 1));
0 голосов
/ 12 июля 2011

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

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

...