Question

What are the key differences between Dictionary.Clear and new Dictionary() in C#? Which one is recommended for which cases?

Was it helpful?

Solution

Dictionary.Clear() will remove all of the KeyValue pairs within the dictionary. Doing new Dictionary() will create a new instance of the dictionary.

If, and only if, the old version of the dictionary is not rooted by another reference, creating a new dictionary will make the entire dictionary, and it's contents (which are not rooted elsewhere) available for cleanup by the GC.

Dictionary.Clear() will make the KeyValue pairs available for cleanup.

In practice, both options will tend to have very similar effects. The difference will be what happens when this is used within a method:

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

OTHER TIPS

As has been extensively covered, the effects are essentially the same. Clear() and new would both give you a fresh Dictionary, essentially abandoning the references to the objects inside of it, freeing them to be collected if they became unrooted.

Technically, .Clear() would have an advantage over new if you were about to repopulate the dictionary to the same size as it was before. This is because it would have been already resized internally to hold the number of objects that you had in it before. Creating a new Dictionary would have a new internal hashtable with the default size, and it would have to be re-expanded as you added items to it.

I would also suggest that they communicate a completely different intent, and you should use .Clear() in your code when you're dealing with the same context as before. Creating a new Dictionary implies that you are about to embark on some new logic dealing with something different than the old Dictionary, while using Clear() indicates that yes, you really wanted to just reset everything you've done so far with it.

Dictionary.Clear()
This will remove all key/value pairs within the Dictionary. The Garbage Collector will clear the memory for these items during the next Garbage Collection Cycle. MSDN

new Dictionary()
Creates a new Dictionary object in memory and abandons the original object. The memory would be cleared during the next Garbage Collection Cycle.

I suppose the key difference is that if you call Dictionary.Clear(), all references to that dictionary will be cleared. If you use new Dictionary(), then the reference you are dealing with at the time will be cleared (in a sense), but all other places you have references won't be since they will still be referring to the old dictionary.

Hopefully this code illustrates it simply:

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);
}

If I had called d1.Clear() instead, then d1 and d2 would have remained in sync, and the subsequent adds would have added to both. The WriteLine calls would both have output '3' instead.

Dictionary.Clear will remove (but not dispose) all items in the instance whereas new Dictionary() will create a brand new instance which just happens to be empty. There may be some subtle implications between the two. Consider the following examples.

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);
  }
}

In the first example all of the contents from the original collection will be printed. That is because the enumerator was created from the reference variable before it was reassigned to a new instance.

In the second example the collection is cleared during an enumeration which will result in an InvalidOperationException because the collection was modified.

I believe that .Clear() was provided so that if your Dictionary is exposed as a read-only property you would be able to remove all of the items. However, if it's not exposed that way, and you have complete control then it might be easier to just instantiate a new Dictionary. There might be a slight performance difference between the two, also.

If you have several references to that dictionary and you clear it you will affect them all where as if you create a new dictionary you will only affect the one new reference. I guess it depends on the scope of the impact that you're aiming for. Obviously a call to "new" will give you a "cleared" dictionary but you might lose other useful state information.

Dictionary.clear will evict all of the items in your dictionary. new Dictionary creates a new dictionary object in memory while orphaning your previous Dictionary for the garbage collector to clean up later.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top