2016-05-10 8 views
0

Ich habe eine Arraylist:Ist das Call-by-Referenz?

ArrayList ReceivedPackets = new ArrayList(); 

Und ich habe eine andere Arraylist:

ArrayList returnList = ReceivedPackets; 

Warum returnList lose es Wert ist, wenn ich diesen Code ausführen?

ArrayList ReceivedPackets = new ArrayList(); // ReceivedPackets is empty 
ReceivedPackets.Add(1);      // Now it has an Integer 
ArrayList returnList = ReceivedPackets;  // Call-by-Reference (I thought), returnList now has an Integer 
ReceivedPackets.clear();      // returnList is empty now. Why? 
+6

'ArrayList' ist Referenzart –

+1

' 'und ReceivedPackets' returnList' sind zwei Referenzvariablen, die auf dasselbe Objekt im Speicher. Änderungen an diesem Objekt werden in beiden widergespiegelt. – David

+0

Wie kann ich ohne ReturnList seinen Wert verlieren? – Christoph

Antwort

2

Wenn Sie dies tun:

ArrayList returnList = ReceivedPackets; 

Sie sind ein neues VariablereturnList genannt zu schaffen, aber diese Variable auf das gleiche In-Memory-Objekt als ReceivedPackets. Es gibt immernoch nur ein aktuelles ArrayList, es sind nur zwei Variablen darauf hinweisend. Änderungen, die an einem vorgenommen werden, spiegeln sich in beiden wider.

Wie kann ich ohne ReturnList seinen Wert verlieren?

Erstellen Sie ein neues Objekt. In seiner einfachsten Form, das würde wie folgt aussehen:

ArrayList returnList = new ArrayList(); 

Wenn Sie auch das Objekt wollen alle Werte von ReceivedPackets enthalten, zum Glück ArrayList hat einen Konstruktor Überlastung, die gerade das tut: Jetzt

ArrayList returnList = new ArrayList(ReceivedPackets); 

Sie hätten zwei Objekte, die Kopien der gleichen Daten enthalten sollten. Änderungen an einem würden sich nicht im anderen widerspiegeln.


In Abwesenheit des Konstruktors hat auch einige ArrayListCopyTo() Methoden, die verwendet werden können Elemente von einem zum anderen zu kopieren. Andernfalls können Sie auch die Quelle ArrayList manuell durchlaufen und Elemente in das Ziel ArrayList kopieren.

Es ist möglich, dass dies ziemlich verwirrend, wenn die ArrayList selbst Objekte Referenz enthält. Weil diese auch mehrere "Zeiger" auf dasselbe speicherinterne Objekt haben können.

Zum Beispiel, wenn Sie ein einzelnes Widget Objekt erstellen und an zwei ArrayList Objekte hinzufügen, werden alle auf die ArrayList Objekte vorgenommenen Änderungen (Hinzufügen/Entfernen von Elementen) unabhängig wäre, sondern jede Modifikation gemacht zum Widget Objekt wäre spiegelt sich in beiden ArrayList s.

Der Punkt ist, dass die ArrayListselbst ein Objekt ist, unabhängig von den Objekten, die es enthält.

Also, abhängig von dem vollen Kontext von dem, was Sie tun, kann Ihre Laufleistung variieren.

1

ArrayList ist ein Referenztyp. Wenn Sie einer Instanz einfach eine Variable zuweisen, verweisen beide Objekte auf denselben Speicherort im Speicher.

Wenn Sie eine Tiefenkopie erstellen möchten, erstellen Sie ein neues Objekt.

static void Main() { 
    ArrayList a = new ArrayList() {1,2,3}; 
    var b = a; 
    var c = new ArrayList(a); 

    a.Clear(); 
    Console.WriteLine(a.Count); // 0 
    Console.WriteLine(b.Count); // 0 
    Console.WriteLine(c.Count); // 3 
}