Da bei einem solchen befehl
myClass class = new myClass();
myClass y = class;
die beiden Instanzen "eine Instanz" sind wäre meine idee gewesen einen Konstruktor zu schreiben der alle variablen kopiert das würde dann so aussehen.
Konstruktor
public myClass(myClass oldClass)
{
this.x = oldClass.x;
.....
}
Aufruf
myClass y = new myClass(class);
warum funktioniert das trotzdem nicht (also wenn ich class.x ändere ändert sich auch y.x mit und umgekehrt)
while(!asleep)
{
sheep++;
}
Hallo baensch,
du hast einen sogenannten Kopierkonstruktor implementiert. Wenn das von dir beschriebene Verhalten auftritt, ist das Feld oder die Eigenschaft x
ein Referenztyp und kein Wertetyp – dessen Wert würde übernommen werden und würde sich bei einer Änderung nicht auf die andere Instanz auswirken. So teilen sich die Instanzen den Referenztyp – du hast in diesem Fall nur eine shallow copy, eine flache Kopie, erstellt.
Wenn du nicht-geteilte Referenztypen in den Instanzen verwenden willst, musst du eine deep copy, eine tiefe Kopie, durchführen.
m0rius
Mein Blog: blog.mariusschulz.com
Hochwertige Malerarbeiten in Magdeburg und Umgebung: M'Decor, Ihr Maler für Magdeburg
Oh das hätte ich auch bemerken können. 🤔
Gibt es da auch eine Einfachere Lösung oder ist die einzige nur wertetypen zu kopieren?
while(!asleep)
{
sheep++;
}
Hallo baensch,
schau dir dazu auch mal das IClonable Interface an:
ggf. hier im Forum danach suchen.
André
Hallo,
wenn ich eine wirkliche Kopie eines Objectes brauche, serialisiere ich es in einen MemoryStream und deserialisiere es wieder. Bisher imho die wirksamste Methode (wenn auch nicht die performanteste).
grüße
Hallo zusammen,
wenn man Objekte kopieren möchte, ist das meistens ein Hinweis darauf, dass mit dem Design was nicht stimmt. Siehe Kopie ohne ICloneable.
herbivore
wenn ich eine wirkliche Kopie eines Objectes brauche, serialisiere ich es in einen MemoryStream und deserialisiere es wieder
Das ist m.E. die wohl schlechteste Lösung. Das IClonable Interface ist doch genau für das Kopieren von Objekten da, und das Objekt selber sollte schon wissen welche referenz Member es neu instanziieren muss!
Again what learned...
@herbivore
wenn man Objekte kopieren möchte, ist das meistens ein Hinweis darauf, dass mit dem Design was nicht stimmt.
Ich habe eine ObservableCollection mit einer selbst geschriebenen Klasse. Diese Klasse besteht aus einer ObservableCollection, die die Geometrie der Instanz beschreibt und eine Variable, die die Qualität der Instanz beschreibt.
Am Anfag ist das StartObjekt und das EndObjekt in der ObservableCollection. Ich berechne den Weg vom Start zum EndObjekt und füge die fehlenden Zwischenschritte ein.
(z.B. Anfang: StartObjekt.Qualität = 0; EndObjekt.Qualität = 3;
Ende(nach meiner Bearbeitung sollte die Collection so aussehen): StarObjekt.Qualität=0; Objekt1.Qualität = 1; Objekt2.Qualität = 2; EndObjekt.Qualität = 3;)
Hättest du vielleicht einen besseren Vorschlag für mein Problem, denn ich sehe keinen anderen Ausweg.
while(!asleep)
{
sheep++;
}
@unconnencted
serialisiere ich es in einen MemoryStream und deserialisiere es wieder
kannst du mir sagen wie das konkret aussieht?
meinst du etwa mit XMLSerializer?
while(!asleep)
{
sheep++;
}
Er meint wahrscheinlich den BinaryFormatter (.Serialize()).
> Codejunky <
danke einmal ich werde die ICloneable Schnittstelle verwenden
while(!asleep)
{
sheep++;
}
Hallo baensch,
Hättest du vielleicht einen besseren Vorschlag für mein Problem, denn ich sehe keinen anderen Ausweg.
ich sehe in deiner Beschreibung keine Stelle, an der Objekte kopiert werden müssen.
herbivore
ich sehe in deiner Beschreibung keine Stelle, an der Objekte kopiert werden müssen
Doch das Objekt1 hat z.B.: genau die selbe Geometrie wie das StartObjekt.
Somit kopiere ich das StartObjekt und ändere nur die Qualität.
Was ist an Clonen so schlecht zieht man daraus irgend welche Nachteile?
while(!asleep)
{
sheep++;
}
Hallo baensch,
was am Kopieren von Objekten schlecht ist, habe ich ja in dem verlinkten Thread beschrieben.
Wobei es in deinem Fall so ist, dass du das zu kopierende Objekt quasi nur als Vorlage für ein echt neues Objekt verwendest. Also das Ganze ein bisschen in Richtung Prototyp (Entwurfsmuster) geht. So ein Vorgehen kann dann schon Sinn machen.
herbivore
Kann sein dass ich zu spät dran bin, aber:
soweit ich das verstanden habe sind in deinem "StartObjekt" Koordinaten eines Punktes drin.
Weiters ist auch die Qualität drin (was auch immer Qualität bedeutet)
Dein Problem ist dass Du einen Punkt (StartObjekt) mit verschiedenen Qualitäten brauchst.
was hältst Du davon wenn Qualität ein eigenes Object wird, initialisiert mit:
Qualität qualität = new Qualität(3);
und dass als Schlüssel in einem Dictionary benützt
dictionary.Add(qualität, startObjekt);
somit hättest Du jedem Punkt eine Qualität verpasst ohne dass Du Dein StartObjekt verändern muss (somit musst du es nicht mehr kopieren)
mbg
Rossegger Robert
mehr fragen mehr wissen
Montag morgen ist die beste Zeit um eine erfolgreiche Woche zu beginnen
Danke spike24,
leider sind die Collection und die Qualität nur die beiden wichtigsten Variablen meiner Klasse somit ist die lösung mit einem Dictionary nicht möglich.
while(!asleep)
{
sheep++;
}
Hmm, also als Abschluss vllt. noch einmal als Erklärung warum ich mich beim (nicht performance kritischen) clonen nicht auf IClonable verlasse..
a. bei großen Daten Objecten sagen wir 20 Propertys aufwärts wird die Clone Methode unübersichtlich, und wenn dann noch collections dabei kommen irgendwann unwartbar.
b. Ich arbeite mit mehreren Entwicklern zusammen, die auch an den erstellten Objecten arbeiten.. und wenns dann mal wieder schnell gehen muss, wird meistens :IClonable und Clone() übersehen, und einfach ein Property hinzugefügt, das dann beim clonen fehlt. (Ich will mich selber da nicht ausschliessen).
Klar wenns um performance geht, ist das natürlich grottig. Aber es läuft stabil und hat sich bewährt.
und wie JunkyXL schon sagte benutze ich tatsächlich den Binary Formatter bzw. den DataContractSerializer (Silverlight)
Grüße
a. bei großen Daten Objecten sagen wir 20 Propertys aufwärts wird die Clone Methode unübersichtlich, und wenn dann noch collections dabei kommen irgendwann unwartbar.
Für diese Fälle gibt es doch die MemberwiseClone-Methode.
Weeks of programming can save you hours of planning
Kleiner ausschnitt aus der doku zu Memberwise Clone
Die MemberwiseClone-Methode erstellt eine flache Kopie, indem ein neues Objekt erstellt wird und anschließend die nicht statischen Felder des aktuellen Objekts in das neue Objekt kopiert werden. Wenn ein Feld ein Werttyp ist, wird das Feld bitweise kopiert. Wenn es sich bei dem Feld um einen Verweistyp handelt, wird nicht das Objekt, auf das verwiesen wird, sondern der Verweis kopiert. Daher verweisen das ursprüngliche Objekt und der Klon auf dasselbe Objekt.
So eine flache Kopie kann man wirklich in den seltensten Fällen gebrauchen.
Ich weiß, auch nicht die Beste Lösung, aber damals hab ich so etwas mal per Reflection gelößt. Ich hatte ein Objekt mit vielen Properties in einer Bibliothek und konnte es nicht ändern, wollte aber eine Kopie ohne jede Property einzeln kopieren zu müssen, da hat sie die Reflection (auch um an private member zu kommen) bewährt. Das konnte ich auch soweit steuern, dass ich einige nicht kopierbare Teile die auch ein BinaryFormatter nicht nimmt (Sockets und so...) manuell auslassen konnte.
Also im groben, mit Reflection ein Objekt auseinander und die Werte in nem neuen Objekt setzten. Alles von außen ohne das zu kopierende Objekt zu ändern.
Ansonsten kann man noch an bestimmten Stellen überlegen Structs zu benutzten. Hab mir dein Beispiel jetzt nicht genau genug angesehen um zu beurteilen ob es dir hilft.