Archiv verlassen und diese Seite im Standarddesign anzeigen : C# - Deep Copy Objekt ohne Referenz
Mr. Lolman
2021-06-10, 16:16:29
Muss ich das echt über eine Erweiterung machen oder das Objekt und alle Unterobjekte neu instanziieren?
Aktuell schwebt mir dieser fiese Hack vor, aber das kanns ja auch nicht sein, oder?
var ObjTemp = new JavaScriptSerializer().Deserialize<ObjClass>(new JavaScriptSerializer().Serialize(Obj));
Die Frage lautet also, kann ich irgendwie ein Objekt kopieren (so wie es mit Array.CopyTo geht), ohne dass ich mir dafür eine Erweiterungsmethode schreiben oder einen fiesen Hack schreiben muss?
Es gibt nicht eingebautes, was man pauschal empfehlen könnte.
Deep clone per Serialisierung hat als Nachteil, dass es nicht besonders schnell ist. Grundsätzlich funktioniert es aber.
https://github.com/MapsterMapper/Mapster#mapping-to-a-new-object wäre mein erster Ansatz für deep cloning. Je nachdem wie die Klassen genau aussehen muss man da evtl. die eine oder andere Konfiguration setzen, aber meistens geht es auch ohne.
Monger
2021-06-10, 20:29:37
Structs sind von Natur aus Call-by-Value, ergo kopieren ist ziemlich simpel.
Darf ich nach dem Anwendungsfall fragen? Weil Deep Copies sind doch eher exotisch.
Mr. Lolman
2021-06-10, 23:07:37
Ich habe einen älteren Source einer Programmbibliothek in dem ich zu 100% die Abwärtskompatiblität gewährleisten muss, also die bestehende Funktionalität in keinster Weise beinflusst werden darf.
Im Methodenaufruf der Programmbibliothek bekomme ich bisher als Parameter eine Liste an Objekten (A1) mit eindeutigen Referenzen zu einer gecachten Liste an anderen komplexen Objekten (A2)
Der Caller kann nun neuerdings auch die gleiche Methode mit einer Liste an Objekten (B1), die auf eine andere gecachte Liste (B2) verweisen, aufrufen. Die anderen Objekte (B2) müssen nun, unter anderem, auch ein Matching auf die bisherige Objektliste (A2) bekommen (also B1->B2->A2 anstatt A1->A2)
Das mache ich indem ich ein Deepcopy (C2) der bisherigen, originalen (A2) Objektliste (A2) mache, dort ein willkürliches Feld für meine Matchingtabelle nutze um damit die fürs Matching notwendigen Inhalte aus C2 holen zu können, und am Ende dennoch die die Originalliste (A2) - die auch von der Software über andere Methoden jederzeit aufgerufen werden kann - nicht manipuliert habe.
Bei der Umsetzung gings mir, wie gesagt, weder um Performance (die externen Calls, die die dll durchführt dauern tw 2 Sekunden und mehr, da sind die paar Millisekunden auch schon wurscht), noch um programmiertechnisch eleganteste Lösung, sondern in erster Linie darum, dass die bestehende Funktionalität jederzeit gewährleistet sein muss (Matching A1 zu A2 und Konsistenz von A2). Redundanzen im Source wollte ich auch vermeiden, , hätt ich einfach den Teil fürs Matching kopiert und da meine Änderungen eingebaut. Anstattdessen hab ich nun an 2 Stellen im alten Source eine zusätzliche Abfrage drinnen: Wenn B1, dann ermittle fürs Matching das passende Objekt aus C2 (mittels dem, von mir missbrauchten Feld), ansonsten (wie bisher) aus A2.
Ich hoff das klingt jetzt nicht allzu verwirrend ;D
Muss denn die Methode mit B1-Objekten auch schreibend auf A2-Objekte zugreifen?
Wenn nicht: weshalb nicht via Matching von B2.ID auf A2.ID (oder Referenz auf A2-Objekt innerhalb des B2-Objekts - jedenfalls wie auch immer man direkt auf A2 zugreifen kann, wozu keine Kopie C, egal ob shallow oder deep, mit extra Zusatzfeld vorhanden sein muss) auf den Inhalt des fraglichen A2 Objekts zugreifen?
Wenn schon: Widerspricht das nicht der Vorgabe, dass sich A2 nicht verändern darf?
Kann auch sehr gut sein, dass ich etwas nicht verstehe ^^
][immy
2021-06-11, 21:06:21
Muss ich das echt über eine Erweiterung machen oder das Objekt und alle Unterobjekte neu instanziieren?
Aktuell schwebt mir dieser fiese Hack vor, aber das kanns ja auch nicht sein, oder?
var ObjTemp = new JavaScriptSerializer().Deserialize<ObjClass>(new JavaScriptSerializer().Serialize(Obj));
Die Frage lautet also, kann ich irgendwie ein Objekt kopieren (so wie es mit Array.CopyTo geht), ohne dass ich mir dafür eine Erweiterungsmethode schreiben oder einen fiesen Hack schreiben muss?
Dann eher den binärserializierer (bin mir beim Namen Grad nicht so sicher, ist laaangne her). Der achtet auch nicht darauf ob eine Klasse als serialisierbar geflaggt ist, sondern macht ganz simpel nen Speicherabbild. Nützlich um Mal eben einen state auf die Platte zu speichern.
Ansonsten gibt es nichts wirklich implementiert. Kann auch verflucht schwierig werden mit allen möglichen Objekten im Hintergrund die du in .net haben kannst.
Zudem ist es nicht Grad sparsam.
Mr. Lolman
2021-06-18, 08:42:29
Wenn nicht: weshalb nicht via Matching von B2.ID auf A2.ID (oder Referenz auf A2-Objekt innerhalb des B2-Objekts - jedenfalls wie auch immer man direkt auf A2 zugreifen kann, wozu keine Kopie C, egal ob shallow oder deep, mit extra Zusatzfeld vorhanden sein muss) auf den Inhalt des fraglichen A2 Objekts zugreifen?
Du hast recht. Ich habs nun so umgebaut, dass ich das Matching über ein Dictionary erledige. (y)
[immy;12704938']Dann eher den binärserializierer
Thx, für den Tipp. Kannte ich bisher nicht.
Du hast recht. Ich habs nun so umgebaut, dass ich das Matching über ein Dictionary erledige. (y)Nice, freut mich :)
[immy;12704938']Dann eher den binärserializierer.
Coole Idee eigentlich :D
vBulletin®, Copyright ©2000-2024, Jelsoft Enterprises Ltd.