In Visual Basic is het vaak nodig om een kopie van een object te maken om gegevens op een nieuwe manier te wijzigen zonder de oorspronkelijke structuur te beïnvloeden. Er ontstaat de taak om oppervlakkige (shallow) en diepe (deep) kopieën te onderscheiden, vooral als objecten geneste referentietypen bevatten.
Achtergrond van de vraag:
Oppervlakkige kopie ën kopiëren alleen de waarden van primitieve eigenschappen en verwijzingen naar geneste objecten, terwijl diepe kopie ën nieuwe instanties van alle geneste objecten maken. Het verschil is cruciaal bij het werken met complexe gegevens, bijvoorbeeld als een object collecties of andere objecten bevat.
Probleem:
Als een object per referentie wordt gekopieerd of de standaardmethode MemberwiseClone wordt gebruikt, zal het wijzigen van geneste objecten de oorspronkelijke structuur samen met de kopie wijzigen - dit is gevaarlijk voor de bedrijfslogica en kan leiden tot moeilijk te vinden bugs.
Oplossing:
In VB.NET is er geen directe kant-en-klare diepe kopie, dus deze moet handmatig of via serialisatie worden geïmplementeerd. Gewoonlijk wordt een gebruikersmethode DeepCopy geïmplementeerd, waarbij nieuwe instanties van alle geneste objecten worden gemaakt.
Voorbeeldcode voor oppervlakkige en diepe kopieën:
Class Person Public Name As String Public Address As Address ' Oppervlakkige kopie Public Function ShallowCopy() As Person Return CType(Me.MemberwiseClone(), Person) End Function ' Diepe kopie 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
Belangrijkste kenmerken:
Wat retourneert de operator = bij het kopiëren van een object van een klasse in Visual Basic?
Antwoord: De operator = voor referentietypen kent een verwijzing toe en kopieert geen waarden. Daarom wijzen beide variabelen naar hetzelfde object.
Dim a As New Person() Dim b As Person = a ' Nu zijn a en b verwijzingen naar hetzelfde object
Kan MemberwiseClone worden gebruikt voor diepe kopieën?
Antwoord: Nee. De methode MemberwiseClone implementeert alleen oppervlakkige kopieën - alle geneste referentietypen worden per referentie gekopieerd.
Waarom is serialisatie niet altijd een universele manier voor diepe kopieën?
Antwoord: Serialisatie werkt alleen met serialiseerbare objecten en ondersteunt mogelijk geen eigenschappen van het type Object of niet gemarkeerd als Serializable. Daarnaast werkt serialisatie trager dan standaard kopiëren.
Een klant kopieert een orderobject met de operator = om een nieuwe bestelling op te stellen, zich niet bewust van de geneste lijst van posities die hetzelfde blijft voor beide objecten.
Voordelen: Snel, eenvoudig
Nadelen: Wijzigingen in één bestelling wijzigen ook de andere - kritieke fouten in de inventaris.
Een DeepCopy-methode is geïmplementeerd om de bestelling samen met alle geneste producten en afleveradressen te kopiëren.
Voordelen: Betrouwbare scheiding van gegevens, correcte bedrijfslogica
Nadelen: Men moet goed letten op de structuur van het object, meer code voor onderhoud