In Visual Basic ist es oft notwendig, eine Kopie eines Objekts zu erstellen, um Daten auf neue Weise zu ändern, ohne die ursprüngliche Struktur zu beeinträchtigen. Es gibt die Aufgabe, flaches (shallow) und tiefes (deep) Kopieren zu unterscheiden, insbesondere wenn Objekte verschachtelte Referenztypen enthalten.
Hintergrund:
Flaches Kopieren kopiert nur die Werte primitiver Eigenschaften und Verweise auf verschachtelte Objekte, während tiefes Kopieren neue Instanzen aller verschachtelten Objekte erstellt. Der Unterschied ist entscheidend bei der Arbeit mit komplexen Daten, zum Beispiel, wenn ein Objekt Sammlungen oder andere Objekte enthält.
Problem:
Wenn man ein Objekt per Referenz kopiert oder die Standardmethode MemberwiseClone verwendet, wird bei der Änderung der verschachtelten Objekte auch die ursprüngliche Struktur zusammen mit der Kopie geändert - dies ist riskant für die Geschäftslogik und kann zu schwer fassbaren Fehlern führen.
Lösung:
In VB.NET gibt es keine direkte Methode für tiefes Kopieren, daher sollte man es manuell oder über Serialisierung implementieren. Üblicherweise wird eine benutzerdefinierte Methode DeepCopy realisiert, wonach neue Instanzen aller verschachtelten Objekte erstellt werden.
Beispielcode für flaches und tiefes Kopieren:
Class Person Public Name As String Public Address As Address ' Flaches Kopieren Public Function ShallowCopy() As Person Return CType(Me.MemberwiseClone(), Person) End Function ' Tiefes Kopieren Public Function DeepCopy() As Person Dim copy As Person = CType(Me.MemberwiseClone(), Person) copy.Address = New Address() With {.City = Me.Address.City} Return copy End Function End Class Class Address Public City As String End Class
Schlüsselfunktionen:
Was gibt der Operator = zurück, wenn man ein Objekt einer Klasse in Visual Basic kopiert?
Antwort: Der Operator = weist für Referenztypen eine Referenz zu und kopiert nicht die Werte. Daher zeigen beide Variablen auf dasselbe Objekt.
Dim a As New Person() Dim b As Person = a ' Jetzt sind a und b Referenzen auf dasselbe Objekt
Kann man MemberwiseClone für tiefes Kopieren verwenden?
Antwort: Nein. Die Methode MemberwiseClone implementiert nur flaches Kopieren - alle verschachtelten Referenztypen werden per Referenz kopiert.
Warum ist Serialisierung nicht immer eine universelle Methode für tiefes Kopieren?
Antwort: Serialisierung funktioniert nur mit serialisierbaren Objekten und unterstützt möglicherweise keine Eigenschaften mit dem Typ Object oder die nicht als Serializable gekennzeichnet sind. Darüber hinaus ist Serialisierung langsamer als das Standardkopieren.
Ein Kunde kopiert ein Bestellobjekt mit dem Operator = zur Erstellung einer neuen Bestellung, ohne zu ahnen, dass die verschachtelte Liste der Positionen für beide Objekte gleich bleibt.
Vorteile: Schnell, einfach
Nachteile: Änderungen in einer Bestellung ändern auch die andere - kritische Fehler in der Warenbuchhaltung.
Eine Methode DeepCopy wurde implementiert, um die Bestellung zusammen mit allen verschachtelten Artikeln und der Lieferadresse zu kopieren.
Vorteile: Zuverlässige Trennung der Daten, korrekte Geschäftslogik
Nachteile: Man muss die Struktur des Objekts genau im Auge behalten, mehr Code für die Wartung