2009-09-09 4 views
27

Was sind die Hauptunterschiede zwischen Dictionary.Clear und new Dictionary() in C#? Welche ist für welche Fälle zu empfehlen?Unterschiede zwischen Dictionary.Clear und neuem Dictionary()

+0

Leistungsbezogene: [die-ist-schneller-klar-Sammlung-oder-Instanziieren-neu] (http://stackoverflow.com/questions/10901020/which-is-faster-clear-collection-or-instantiate- neu) – nawfal

Antwort

32

Dictionary.Clear() entfernt alle KeyValue Paare im Wörterbuch. Doing new Dictionary() erstellt eine neue Instanz des Wörterbuchs.

Wenn und nur wenn die alte Version des Wörterbuchs nicht von einer anderen Referenz verwurzelt ist, erstellt das Erstellen eines neuen Wörterbuchs das gesamte Wörterbuch und dessen Inhalte (die nicht an anderer Stelle verwurzelt sind) zur Bereinigung durch den GC verfügbar.

Dictionary.Clear() wird die KeyValue Paare für die Bereinigung verfügbar machen.

In der Praxis werden beide Optionen sehr ähnliche Auswirkungen haben. Der Unterschied wird sein, was passiert, wenn diese in einem Verfahren verwendet wird:

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

@divo - Ich denke, er meint eine Kopie der Referenz, keine Kopie des Objekts selbst –

+0

@John: Das war genau das, was ich meinte. Es ist eine Kopie - eine Kopie des Verweises auf das Wörterbuch –

0

Dictionary.clear löscht alle Elemente in Ihrem Wörterbuch. new Dictionary erstellt ein neues Wörterbuchobjekt im Speicher, während das vorherige Wörterbuch verwässert wird, damit der Garbage Collector später bereinigt wird.

+0

Können wir besser als "höchstwahrscheinlich"? Das wird hier eine Schlüsselfrage sein. –

+0

Ich glaube nicht, dass das Wörterbuch jemals Dispose für Elemente, die es enthält, aufrufen wird; Wenn die Gegenstände wegwerfbar sind, sollten Sie einen expliziten Code schreiben, um sie zu entsorgen. – ChrisW

+1

Warum sollte es über etwas verfügen? Nur weil sie in einem Wörterbuch sind, bedeutet das nicht, dass sie nicht woanders verwendet werden. Das wäre schrecklich buggy. Alles, was es tut, ist null die Hashtable-Buckets. – womp

14

Dictionary.Clear()
Dadurch werden alle Schlüssel/Wert-Paare im Wörterbuch entfernen. Der Garbage Collector löscht den Speicher für diese Elemente während des nächsten Garbage Collection Cycle. MSDN

neues Wörterbuch()
Erstellt ein neues Dictionary-Objekt im Speicher und verzichtet auf das ursprüngliche Objekt. Der Speicher wird während des nächsten Sammlungszyklus gelöscht.

+0

Dieser MSDN Artikel sagt nichts über die Entsorgung. –

+3

Etwas zu beachten - wenn Ihr Wörterbuch sehr groß ist und Sie sicher sind, dass Sie nach dem Löschen ungefähr dasselbe über Daten laden werden - die Tatsache, dass Dictionary.Clear() die Kapazität des Wörterbuchs nicht zurücksetzt es ist attraktiver. – overslacked

+0

@overslacked - Verdammt, ich habe gerade Zeit damit verbracht, eine Antwort zu schreiben, die genau das nahelegte. – womp

5

Ich nehme an dem entscheidenden Unterschied, dass, wenn Sie Dictionary.Clear() nennen, alle Verweise auf dieses Wörterbuch gelöscht werden. Wenn Sie new Dictionary() verwenden, wird die Referenz, mit der Sie gerade arbeiten, gelöscht (in gewissem Sinne), aber alle anderen Stellen, an denen Sie Referenzen haben, sind nicht vorhanden, da sie sich immer noch auf das alte Wörterbuch beziehen.

Hoffentlich Code zeigt es einfach:

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

Wenn ich d1.Clear() stattdessen genannt hatte, dann d1 und d2 synchron geblieben wäre, und die nachfolgende fügt beide hinzugefügt haben würde. Die WriteLine-Aufrufe würden beide stattdessen "3" ausgeben.

+0

+1 - das ist der Hauptunterschied. – Joe

1

Wenn Sie mehrere Verweise auf dieses Wörterbuch haben und es löschen, wirken sich alle auf Sie aus. Wenn Sie ein neues Wörterbuch erstellen, wirkt sich dies nur auf die neue Referenz aus. Ich schätze, es hängt vom Umfang der Auswirkungen ab, die Sie anstreben. Offensichtlich wird ein Aufruf von "neu" Ihnen ein "gelöschtes" Wörterbuch geben, aber Sie könnten andere nützliche Statusinformationen verlieren.

5

Dictionary.Clear wird alle Objekte in der Instanz entfernen (aber nicht entsorgen), während new Dictionary() eine brandneue Instanz erstellt, die zufällig leer ist. Es könnte einige subtile Implikationen zwischen den beiden geben. Betrachten Sie die folgenden Beispiele.

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

Im ersten Beispiel werden alle Inhalte der Originalsammlung gedruckt.Dies liegt daran, dass der Enumerator aus der Referenzvariablen erstellt wurde, bevor er einer neuen Instanz zugewiesen wurde.

Im zweiten Beispiel wird die Sammlung während einer Aufzählung gelöscht, was zu einer InvalidOperationException führt, weil die Sammlung geändert wurde.

19

Wie ausführlich behandelt wurde, sind die Auswirkungen im Wesentlichen die gleichen. Clear() und new würden Sie beide ein neues Wörterbuch geben, das im Wesentlichen die Verweise auf die darin enthaltenen Objekte aufgibt und sie freigibt, um gesammelt zu werden, wenn sie entwurzelt wurden.

Technisch gesehen hätte .Clear() einen Vorteil gegenüber new, wenn Sie das Wörterbuch auf die gleiche Größe wie zuvor auffüllen würden. Dies liegt daran, dass die Größe bereits intern geändert wurde, um die Anzahl der Objekte zu enthalten, die Sie zuvor darin hatten. Das Erstellen eines neuen Dictionarys hätte eine neue interne Hashtabelle mit der Standardgröße, die beim Hinzufügen von Elementen erneut erweitert werden müsste.

Ich würde auch vorschlagen, dass sie eine völlig andere Absicht kommunizieren, und Sie sollten .Clear() in Ihrem Code verwenden, wenn Sie mit dem gleichen Kontext wie zuvor beschäftigen. Das Erstellen eines neuen Wörterbuchs bedeutet, dass Sie sich auf eine neue Logik einlassen, die etwas anderes als das alte Wörterbuch behandelt, während Clear() bedeutet, dass Sie wirklich alles zurücksetzen wollten, was Sie bisher getan haben.

+4

> Erstellen eines neuen Dictionary würde eine neue interne Hashtabelle mit der Standardgröße haben - nicht unbedingt, können Sie eine Konstruktorüberladung verwenden, um die Anfangskapazität festzulegen. – Joe

+4

Ja. Ich nahm nur ein .Clear() vs. ein neues Dictionary() an. – womp

3

Ich glaube, dass .Clear() wurde zur Verfügung gestellt, so dass, wenn Ihr Wörterbuch als schreibgeschützte Eigenschaft ausgesetzt ist, Sie alle Elemente entfernen können. Wenn dies jedoch nicht der Fall ist und Sie die vollständige Kontrolle haben, ist es möglicherweise einfacher, ein neues Dictionary zu instanziieren. Es könnte auch einen kleinen Leistungsunterschied zwischen den beiden geben.

Verwandte Themen