abstract + ICloneable Clone
-
Hallo!
Wie und wo implementiert man die Funktion Clone() bei abstrakten Klassen am besten.
Meine Idee:abstract class Device : ICloneable { . . public object Clone() { //Was muss ich hier reinschreiben das am Ende der Typ passt?? Typ_der_ich_bin t = new Typ_der_ich_bin(this); //Typ_der_ich_bin ist entweder Device1 oder Device2 return t; } } class Device1: Device { } class Device2: Device { }
Irgendwie stehe ich voll am Schlauch? Wie komme ich an den Typ. Wie implementiere ich das ganze?
Kann mir da jemand weiterhelfen?Lg THE_ONE
-
this.GetType();
-
Hallo!
Könntest du mir bitte die ganze Codezeile aufschreiben verstehe nicht ganz wo in meinem Programm ich das einfügen soll?
Lg THE_ONE
-
public object Clone() { //Was muss ich hier reinschreiben das am Ende der Typ passt?? Typ_der_ich_bin t = this.GetType(); //Typ_der_ich_bin ist entweder Device1 oder Device2 return t; }
-
Also wenn Du deinem zu klonenden Objekt eh schon this übergibst, dann kannst Du gleich die Clone() Methoden nur in den abgeleiteten Klassen impl.
Falls Du einfach Klonen möchtest kannst Du mit dem serialize / deserialize Trick arbeiten.
Oder Du setzt die Klasse Acttivator ein:
Bsp:T item = (T)Activator.CreateInstance(typeof(T), new object[] { ... });
Simon
-
Firefighter schrieb:
public object Clone() { //Was muss ich hier reinschreiben das am Ende der Typ passt?? Typ_der_ich_bin t = this.GetType(); //Typ_der_ich_bin ist entweder Device1 oder Device2 return t; }
Fehler 1 Der Typ- oder Namespacename "Typ_der_ich_bin" konnte nicht gefunden werden. (Fehlt eine Using-Direktive oder ein Assemblyverweis?) C:\csharp\SimulationSetup\SimulationSetup\Device.cs 139 13 SimulationSetup
-
-.- Nich dein Ernst oder?
Type t = this.GetType();
Aber wie gesagt, setz es so um wie es theta schon gesagt hat. Indem du die Clone Methode in den Abgeleiteten Klassen implementierst.
-
theta schrieb:
Also wenn Du deinem zu klonenden Objekt eh schon this übergibst, dann kannst Du gleich die Clone() Methoden nur in den abgeleiteten Klassen impl.
Das werde ich wahrscheinlich machen das es am einfachsten für mich ist, obwohl bei 30 verschiedenen Devicetypen würde es nicht so lustig sein.
Das mit dem serialisieren verstehe ich leider nicht.-> Heist das einfach nur dass ich es in ein File schreiben soll und dann wieder rauslesen soll und in ein neues Objekt schreiben soll?
theta schrieb:
Oder Du setzt die Klasse Acttivator ein:
Bsp:T item = (T)Activator.CreateInstance(typeof(T), new object[] { ... });
Schreibe ich dass in die Clone Methode der Abstrakten Klasse??
Wenn ja was muss ich dann für T schreiben in meinem konkreten Beispiel?? Das Problem ist ja, dass ich T nicht kenne.
-
Firefighter schrieb:
-.- Nich dein Ernst oder?
Type t = this.GetType();
Das zwar nicht
Aber was mache ich nun mit diesem t?
kann ja schlechtpublic virtual object Clone() { Type t = this.GetType(); t gg = new t(); return gg; }
schreiben.
Was soll ich mit dem t weitermachen?Firefighter schrieb:
Aber wie gesagt, setz es so um wie es theta schon gesagt hat. Indem du die Clone Methode in den Abgeleiteten Klassen implementierst.
Also so????
abstract class Device { . . } class Device1: Device, ICloneable { public object Clone() { ... } } class Device2: Device, ICloneable { . . public object Clone() { ... } }
-
THE_ONE schrieb:
theta schrieb:
Also wenn Du deinem zu klonenden Objekt eh schon this übergibst, dann kannst Du gleich die Clone() Methoden nur in den abgeleiteten Klassen impl.
Das werde ich wahrscheinlich machen das es am einfachsten für mich ist, obwohl bei 30 verschiedenen Devicetypen würde es nicht so lustig sein.
Das mit dem serialisieren verstehe ich leider nicht.-> Heist das einfach nur dass ich es in ein File schreiben soll und dann wieder rauslesen soll und in ein neues Objekt schreiben soll?
theta schrieb:
Oder Du setzt die Klasse Acttivator ein:
Bsp:T item = (T)Activator.CreateInstance(typeof(T), new object[] { ... });
Schreibe ich dass in die Clone Methode der Abstrakten Klasse??
Wenn ja was muss ich dann für T schreiben in meinem konkreten Beispiel?? Das Problem ist ja, dass ich T nicht kenne.Das schreibst Du in die abstrakte Klasse.
Du musst einen Type übergeben und ich habe in meinem Bsp einfach typeof(T) genommen, Du nimmst this.GetType()...
Simon
-
theta schrieb:
Du musst einen Type übergeben und ich habe in meinem Bsp einfach typeof(T) genommen, Du nimmst this.GetType()...
SimonDas war mir klar dass ich statt typeof(T) einfach this.GetType() nehmen muss. Leider ist mir nicht klar was ich statt dem T item schreiben soll, ich kenne das T ja nicht?
T item = (T)(Activator.CreateInstance(this.GetType()));
Das einzige was ich bis jetzt ohne Fehler zum laufen bekommen habe (also kein PSEUDO Code) ist das:
public override object Clone() { object newInstance = Activator.CreateInstance(this.GetType()); return newInstance; }
Nur leider ist newInstance leider nicht vom Type this.GetType() sondern vom Type object.
-
Um wat geht es denn bei deiner Clone Methode überhaupt?Soll sie ein neues Element eines Device zurückgeben oder wie?Dann mach das doch einfach so
public object Clone() { Device newInstance = Activator.CreateInstance(this.GetType()); return newInstance; }
Oder hab ich das falsch verstanden?
-
Firefighter schrieb:
Um wat geht es denn bei deiner Clone Methode überhaupt?Soll sie ein neues Element eines Device zurückgeben oder wie?Dann mach das doch einfach so
public object Clone() { Device newInstance = Activator.CreateInstance(this.GetType()); return newInstance; }
Oder hab ich das falsch verstanden?
Nein du hast das richtig verstanden.
Genau das hatte ich schon selbst probiert gehabt.
Leider mit dem FehlerFehler 1 Der Typ "object" kann nicht implizit in "SimulationSetup.Device" konvertiert werden. Es ist bereits eine explizite Konvertierung vorhanden. (Möglicherweise fehlt eine Umwandlung.) C:\csharp\SimulationSetup\SimulationSetup\Device.cs 139 34 SimulationSetup
-
In der Compilerfehlermeldung steht doch schon alles:
Möglicherweise fehlt eine Umwandlung.
!!!
-
also das Clone soll mir je nach Ausgangsobject (Device1 oder Device2) ein Device1 oder Device2 zurückliefern mit dem Inhalt das Ausgangsobjects.
Also genau das was man sich von einem Clone erwarte. Ein komplett identisches Replikat des anderen.
So wie bei dem Schaf Dolly. Nach dem clonen waren da 2 identische Schafe. Nicht nur dass es ein Tier (Device) war sondern es war wieder ein Schaf mit exakt den gleichen Merkmalen wie das Ausgangsschaf (eine exakte Kopie vom Ausgangsschaf )(z.B.: Instanz von Device1 - alle Variablen der Instanzen haben den gleichen Inhalt).Ich will also nicht nur eine Clone Funktion für ein bestimmtes Tier (Schaf - z.B Device1) sondern eine Clone Funktion für alle Tiere (Device).
-
Das Problem ist zu definieren was mit "genau identisch" gemeint ist. Willst du eine flache oder eine tiefe Kopie?
-
O.o schrieb:
Das Problem ist zu definieren was mit "genau identisch" gemeint ist. Willst du eine flache oder eine tiefe Kopie?
meine Classendefinition:
abstract class Device : ICloneable { private static long idcounter = 0; protected Point position; protected Point midpoint; protected Bitmap symbol; protected int type; protected bool selected; protected long id; protected long connectedWith;
Alle diese Werte sollen gleich sein, also würde ich tief sagen.
da von position,midpoint und symbol neue Instanzen angelegt werden müssen, obwohl mit gleichem Inhalt.
-
Du hast nicht verstanden worauf ich hinaus will.
Willst du, dass nach dem klonen jedes Schaf seine eigenen Eingeweide hat (tiefe Kopie) oder willst du, dass sie sich die Eingeweide teilen, siamesische Zwillinge sozusagen (flache Kopie).
Du musst dir im Klaren sein, wenn du eine tiefe Kopie willst, dass das je nach Komplexität des zu klonenden Objekts ziemlich ausarten kann.
Das Problem an einer flachen Kopie ist aber, dass wenn du im einen Objekt, z.B. die Einträge einer Liste veränderst, diese sich im anderen Objekt genauso ändert (es werden nur die Referenzen kopiert, nicht die Objekte selbst).
-
Ich will Clonen und nicht Frankenstein spielen.
Also jedes Schaf hat seine eigenen Eingeweide.
Also tiefe Kopie.
-
Dann weißt du ja was zu zu tun hast.
Value-types kannst du ohne Bedenken so kopieren.
Reference-types musst du entweder über ICloneable.Clone klonen oder sie "von Hand" kopieren.abstract class Device : ICloneable { public object Clone() { Device clone = new Device(); clone.position = this.position; clone.symbol = this.position.Clone(); // usw. usf. } }