Ich lerne C # Deep Copy und Shallow Copy. Hier wird nach dem Ändern von demo_obj1 der Objektwert geändert, aber die Liste wird nicht aktualisiert, aber in demo_obj2 wird der Objektwert geändert und auch der Listenwert aktualisiert. Wer weiß, was hier passiert? Danke
Visual Studio 2017
.Net Framework 4.6
%Vor%Ausgabe:
%Vor%Es hat nichts mit Klonen zu tun, es ist das Problem der Referenzen.
Sie haben zwei Objekte obj1
und obj2
erstellt und in eine Liste eingefügt.
Jetzt iterieren Sie durch die Sammlung, geben sie aus und erhalten die erwarteten Ergebnisse.
Referenzen sind die folgenden jetzt:
%Vor% Später haben Sie nach obj1 = obj2
eine Referenz von obj2
zu obj1
zugewiesen. Du änderst nicht seinen Wert oder kopierst dein Objekt, du kopierst einfach die Referenz und lässt sie auf ein anderes Objekt zeigen
Also, beide zeigen jetzt auf das gleiche Objekt
Liste enthält die gleichen zwei Verweise auf verschiedene Objekte.
Dann macht obj2.Value = 200
seinen Wert tatsächlich auf 200:
Wenn Sie jetzt obj1
und obj2
UIDs und Werte ausgeben, geben Sie den Wert des gleichen Objekts (Demo_obj2) aus.
Wenn Sie jedoch versuchen, die Auflistung zu durchlaufen, erhalten Sie Demo_obj1
und Demo_obj2
gemäß der Verweistabelle erneut.
Ich denke also, es gibt ein paar Punkte, die Sie aus dieser Frage verstehen müssen.
Erstens gibt dir die clone()
-Methode in Bezug auf deine tatsächliche Frage tatsächlich 2 Objekte. Beide beginnen mit dem Wert 100
und werden zu einer Liste hinzugefügt. Beachten Sie, dass diese Liste auf die Objekte verweist, die in obj1
und obj2
enthalten sind und nicht die Referenzen verwenden, die Sie bereits erstellt haben.
Dann machst du das:
%Vor% Das bedeutet, dass du deine Referenz obj1
auf obj2
aktualisierst, so dass nun beide auf dasselbe Objekt zeigen. Sie können dies sehen, wenn Sie sich anmelden und 200
zweimal sehen. Beachten Sie, dass Sie die Zeiger in Ihrer Liste nicht aktualisiert haben, da es sich um völlig verschiedene Zeiger handelt.
Schließlich, wenn Sie Ihr zweites Protokoll ausführen, sehen Sie mithilfe der Zeiger in der Liste das ursprüngliche obj1
mit dem Wert 100
und das zweite obj2
, das Sie aktualisiert haben, mit dem Wert 200
.
Das Interessante hier ist, dass es sich nicht wirklich um ein sehr gutes Beispiel für einen tiefen Klon handelt, weil Sie primitive Werte verwenden, die sowieso nur kopiert werden. Um ein besseres Ergebnis zu erzielen, möchten Sie wahrscheinlich einige Werte innerhalb eines Objekts umbrechen:
%Vor% Wenn Sie jetzt einen Balken erstellen und einen flachen Klon von Foo
erstellen, würde er immer noch den gleichen Bar
verwenden. Also:
Hier müssen Sie in Deep Cloning gehen, damit jede Foo
Instanz eine andere Referenz als eine eindeutige Bar
verwendet.
Sie haben die Variable obj1
als Instanz in obj2
festgelegt. Der ursprüngliche Wert von obj1
ist weiterhin in der Liste vorhanden. In der Zeile, in der Sie obj1 = obj2;
eingeben, wird die Variable obj1
auf obj2
gesetzt. Es ersetzt nicht die Werte der Instanz, die zuvor in obj1
gespeichert wurde. Aus diesem Grund sehen Sie die Ausgaben, die Sie beschreiben.
Vergessen Sie MemberwiseClone
, es ist ein Ablenkungsmanöver hier.
Ihr Problem ist hier:
%Vor% Das bedeutet also, dass obj1 = obj2; obj1.Value = 200;
Folgendes tut:
obj2
gespeicherten Wert (die Adresse, an der die Instanz { "Demo_obj2"; 100 }
lebt. obj1
. Der Wert obj1
ist jetzt die Adresse, an der dieselbe Instanz { "Demo_obj2"; 100 }
lebt; Sowohl obj1
als auch obj2
zeigen auf dasselbe Objekt . Value
des Objekts, auf das von obj1
(oder obj2
) verwiesen wird, auf 200
: das Ergebnis ist die Instanz { "Demo_obj2"; 200 }
. { "Demo_obj1"; 100 }
zuvor referenzierte Instanz obj1
wird von keiner Ihrer beiden Variablen obj1
oder obj2
mehr referenziert, aber die Instanz wird noch gespeichert ( Sie haben sie nicht berührt! <) / em>) in der Liste und erreichbar über objList[0]
. Verstehen Sie jetzt, warum Sie das Verhalten erhalten, das Sie sehen?
Tags und Links c#