Entwickler-Ecke

C# - Die Sprache - Flache und Tiefe Kopie


Barbidi - Mi 13.01.10 11:38
Titel: Flache und Tiefe Kopie
Moin moin,
ich studiere immoment im ersten Semster und demnächst stehen die Prüfungen an, unteranderem auch ich Informatik.
Wird programmieren dort mit C#. Ich habe so gut wie alles verstanden nur leider habe kein Idee wie ich eine Flache Kopie bzw eine Tiefe Kopie in einem Programm schreiben könnte.
Vllt kann mir ja jemand:)
Danke im Vorraus

grüße Barbidi


danielf - Mi 13.01.10 11:59

Hallo,
unter einer flachen Kopie versteht man, wenn man nur die Referenzen kopiert. Eine tiefe Kopie ist, wenn auch das unterste Element wirklich kopiert wurde (und nicht nur per REferenz darauf gezeigt wird).

Zum Beispiel:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
List<object> orginalListe = new List<object>();
orginalListe.Add(new object());
orginalListe.Add(new object());
orginalListe.Add(new object());

List<object> flacheKopie = new List<object>();
// referenzen werden zugewiesen
flachKopie.Add(orginalListe[0]);
flachKopie.Add(orginalListe[1]);
flachKopie.Add(orginalListe[2]);

List<object> tiefeKopie = new List<object>();
// für den Fall, das Clone implementiert ist
tiefeKopie.Add(orginalListe[0].Clone());
tiefeKopie.Add(orginalListe[1].Clone());
tiefeKopie.Add(orginalListe[2].Clone());


Ich hoffe das hilf (code ist frei geschrieben und kann fehler beinhalten, soll aber nur ein Beispielhaft sein)

Gruß Daniel


Barbidi - Mi 13.01.10 12:27

gibt es da auch noch eine andere möglichkeit? Ich habe nämlcih noch nie Clone benutzt.


danielf - Mi 13.01.10 12:39

Wie kopierst du den ein Objekt? Dann nehme diese Vorgehensweise.


Barbidi - Mi 13.01.10 17:39

das ja eben das problem, ich habe, wie es aussieht das problem, dass ich nicht merke was ich da genau tue.;)
geht es denn nicht anderes außer clone?


danielf - Mi 13.01.10 18:04

Wie man kopiert ist Objekt-abhänig.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
class TestKoord
{
   public int X { get; set; }
   public int Y { get ; set; }

   public TestKoord( int x, int y)
   { X = x; Y = y; }
}
....

   TestKoord a = new TestKoord(54);

   TestKoord tiefeKopieVonA = new TestKoord(a.X, a.Y);


hmm.. blödes Beispiel :) Vom typ int bekommt man immer eine tiefe Kopie.


Anderes Beispiel:
Angenommen die Eigenschaften X und Y sind vom Typ eines komplexen Objekts, dann ist (siehe Kommentar)

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
class TestKoord
{
   public KomplexesObjet X { get; set; }
   public KomplexesObjet Y { get ; set; }

   public TestKoord( KomplexesObjet x, KomplexesObjet y)
   { X = x; Y = y; }
}
....

   TestKoord a = new TestKoord(x,y);

   // bei einer Flache Kopie werden nur die Referenz der "SubObjekte" mitgegeben
   // (Es werden keine neue SubObjekte erstellt
   TestKoord flacheKopieVonA = new TestKoord(a.X,b.Y);

   // bei einer tiefen Kopie werden die "SubObjekte" wirklich kopiert
   // (Es entstehen NEUE klone (andere Speicheradresse) von den SubOBjekten)
   TestKoord tiefeKopieVonA = new TestKoord(x.clone(), y.clone());


Tu mir schwer beim erklären :/

Flache Kopie: Neues Objekt des BasisObjekt, aber nur Refernzen (verwendet gleiche Objekte wir ursprüngliches Objekt) der SubObjekte/Eigenschaften
Tiefe Kopie: Neue SubObjekte des BasisObjekt und neue SubObjekte (eigner Speicherbereich)

Ich werde mal nach Literatur schauen, die das vlt. deutlicher erklärt sowie ein Beispiel implementieren, dafür hab ich aber wohl erst nächste Woche Zeit.

Mfg Daniel


JüTho - Mi 13.01.10 18:32

Vielleicht hilft dieses Beispiel beim Verständnis:

Du hast ein Auto mit einem bestimmten Kennzeichen.

Flache Kopie: Du bekommst ein zweites Kennzeichen für das alte Auto. Dann hast du immer noch dasselbe Auto, aber zwei verschiedene Kennzeichen, unter denen dieses Auto registriert ist. (OK, jeder Vergleich hinkt; für ein privates Auto geht das nicht, aber z.B. bei einem Dienstwagen für Angela Merkel...)

Tiefe Kopie: Du bekommst ein neues Auto mit gleichen Eigenschaften und einem neuen Kennzeichen. Dann gibt es auf den Straßen zwei Autos, die gleich aussehen (und sich gleich verhalten), aber an völlig verschiedenen Stellen herumfahren und unter zwei verschiedenen Kennzeichen zu finden sind.

Gruß Jürgen


Kha - Mi 13.01.10 19:17

Am Rande will ich noch erwähnen, dass a) (was user profile icondanielf schon angesprochen hat) Wertetypen immer tief kopiert werden (solange sie nicht selbst wieder Referenztypen enthalten) und b) Clone überhaupt meistens [http://www.mycsharp.de/wbb2/thread.php?postid=43172#post43172] der falsche Weg ist ;) .

Wobei das Interface ICloneable sowieso völlig verquer ist, da es schonmal keine Aussagen eben über flache oder tiefe Kopie macht. Ich kann mir jedenfalls keine Situation vorstellen, in der ich einen ICloneable-Parameter bräuchte :nixweiss: .
Wenn, dann schon wie z.B. List<T>: Kein nichtsaussagendes Interface implementieren, sondern einfach im Konstruktor übergeben.