2016-12-04 2 views

Antwort

5

Das Problem mit dem Klonen von Objekten und insbesondere der ICloneable Schnittstelle ist, dass die öffentliche Schnittstelle die Absicht nicht gut kommuniziert.

Nämlich - wird so Clone Funktion der List<T> Klon enthaltenen Elemente auch, oder klonen Sie einfach die Liste und kopieren Sie die Verweise auf enthaltene Elemente? Flache Kopie, die Kopien der Referenzen und schafft nur die neue Liste wäre gleichbedeutend mit dieser:

List<T> clone = new List<T>(originalList); 

Wenn Sie jedoch alle enthaltenen Elemente zwingen wollte auch geklont werden, dann wäre es zu diesem gleichwertig sein :

List<T> clone = originalList.Select(x => (T)x.Clone()).ToList(); 

Dies setzt voraus, dass der Typ TICloneable umsetzt. Aber selbst mit dieser Lösung können die genauen Auswirkungen der Codeausführung nicht im Voraus erklärt werden. Was bedeutet es für ein Element x sich zu klonen? Wird es eine flache Kopie sein (angeboten von der MemberwiseClone Methode erbt es Formular System.Object), oder wird es eine tiefe Kopie sein. Und wenn tief, was passiert, wenn zwei Objekte in der Liste auf dasselbe dritte Objekt verweisen? Wird das dritte Objekt zweimal oder nur einmal kopiert? Und so weiter ... Sie können sehen, wohin das geht.

Aus den oben genannten Gründen sind die Klonierungsfunktionen nicht in das Framework integriert. Es bleibt dem benutzerdefinierten Code überlassen, zu entscheiden, was es bedeutet, ein Objekt zu klonen und dann benutzerdefinierten Code dafür zu implementieren.

0

Weil List<T> nicht von IClonable erbt. Wenn Sie einen Klon einer Liste tun möchten Sie tun könnten ...

var t = new List<IClonable>(); 
var newList = t.Select(a=>a.Clone()).ToList(); 
+1

vor allem, weil Sie in der Lage sein sollten, alles in einer Liste zu speichern, unabhängig davon, ob die Elemente klonbar sind oder nicht – TerribleDev

4

Um einen klonbar List Art machen würden Sie tun:

public class CloneableList<T> : List<T>, ICloneable 
{ 
    public object Clone() { 
     var clone = new CloneableList<T>(); 
     clone.AddRange(this); 
     return clone; 
    } 
} 

oder dies, falls Sie es tief geklont:

public class DeepCloneableList<T> : List<T>, ICloneable where T : ICloneable 
{ 
    public object Clone() { 
     var clone = new DeepCloneableList<T>(); 
     clone.AddRange(this.Select(x => (T)x.Clone())); 
     return clone; 
    } 
} 
Verwandte Themen