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

Различия между Dictionary.Clear и новым словарем()

Каковы основные различия между Dictionary.Clear и new Dictionary() в С#? Какой из них рекомендуется для каких случаев?

4b9b3361

Ответ 1

Dictionary.Clear() удалит все пары KeyValue в словаре. Выполнение new Dictionary() создаст новый экземпляр словаря.

Если и только в том случае, если старая версия словаря не связана с другой ссылкой, создание нового словаря сделает весь словарь, а содержимое (которое не внедрено в другое место) доступно для очистки GC.

Dictionary.Clear() сделает пары KeyValue доступными для очистки.

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

void NewDictionary(Dictionary<string,int> dict)
{
   dict = new Dictionary<string,int>(); // Just changes the local reference
}

void  ClearDictionary(Dictionary<string,int> dict)
{
   dict.Clear();
}

// When you use this...
Dictionary<string,int> myDictionary = ...; // Set up and fill dictionary

NewDictionary(myDictionary);
// myDictionary is unchanged here, since we made a new copy, but didn't change the original instance

ClearDictionary(myDictionary);
// myDictionary is now empty

Ответ 2

Как было широко охвачено, эффекты по существу одинаковы. Clear() и new оба дадут вам свежий Словарь, по сути отказываясь от ссылок на объекты внутри него, освобождая их для сбора, если они будут выведены из строя.

Технически, .Clear() будет иметь преимущество перед new, если вы собираетесь повторно заполнить словарь до того же размера, что и раньше. Это связано с тем, что он уже был изменен внутренне, чтобы удерживать количество объектов, которые у вас были в нем раньше. Создание нового словаря будет иметь новую внутреннюю хэш-таблицу с размером по умолчанию, и ее нужно будет повторно расширить по мере добавления элементов к ней.

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

Ответ 3

Dictionary.Clear()
Это приведет к удалению всех пар ключ/значение в словаре. Сборщик мусора очистит память этих предметов во время следующего цикла сбора мусора. MSDN

новый словарь()
Создает новый объект Dictionary в памяти и оставляет исходный объект. Память будет очищена во время следующего цикла сбора мусора.

Ответ 4

Я полагаю, что ключевое различие заключается в том, что если вы вызываете Dictionary.Clear(), все ссылки на этот словарь будут очищены. Если вы используете new Dictionary(), тогда ссылка, с которой вы работаете в данный момент, будет очищена (в некотором смысле), но во всех других местах, где у вас есть ссылки, не будет, так как они все равно будут ссылаться на старый словарь.

Надеюсь, этот код просто иллюстрирует это:

public void Method()
{
    Dictionary<int, int> d1 = new Dictionary();

    d1.Add(1,1);
    d1.Add(2,3);

    Dictionary<int, int> d2 = d1;

    //this line only 'clears' d1
    d1 = new Dictionary();

    d1.Add(1,1);
    d1.Add(3,5);
    d2.Add(2,2);

    //writes '2' followed by '1'
    Console.WriteLine(d1.Count);
    Console.WriteLine(d2.Count);
}

Если бы я назвал d1.Clear() вместо этого, тогда d1 и d2 оставались бы в синхронизации, и последующие добавления добавили бы к обоим. У вызовов WriteLine оба будут иметь выход "3".

Ответ 5

Dictionary.Clear удалит (но не удалит) все элементы в экземпляре, тогда как new Dictionary() создаст совершенно новый экземпляр, который просто окажется пустым. Между ними могут быть некоторые тонкие последствия. Рассмотрим следующие примеры.

void Example1()
{
  var collection = new Dictionary<string, string>();
  collection.Add("key1", "value1");
  collection.Add("key2", "value2");
  foreach (var kvp in collection)
  {
    collection = new Dictionary<string, string>();
    Console.WriteLine(kvp);
  }
}

void Example2()
{
  var collection = new Dictionary<string, string>();
  collection.Add("key1", "value1");
  collection.Add("key2", "value2");
  foreach (var kvp in collection)
  {
    collection.Clear();
    Console.WriteLine(kvp);
  }
}

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

Во втором примере коллекция очищается во время перечисления, что приведет к InvalidOperationException, потому что коллекция была изменена.

Ответ 6

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

Ответ 7

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

Ответ 8

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