Nach eingehender Lektüre vieler der hier verlinkten Optionen und möglicher Lösungen für dieses Problem bin ich der Meinung alle Optionen sind gut zusammengefasst unter Ian P. Der Link (alle anderen Optionen sind Abwandlungen dieser Optionen) und die beste Lösung wird durch Pedro77 Der Link auf die Kommentare zur Frage.
Daher kopiere ich hier nur die relevanten Teile dieser 2 Referenzen. Auf diese Weise können wir haben:
Das Beste für das Klonen von Objekten in C sharp!
Das sind in erster Linie alle unsere Möglichkeiten:
El Artikel Schnelle tiefe Kopie durch Ausdrucksbäume hat auch einen Leistungsvergleich des Klonens durch Serialisierung, Reflection und Expression Trees.
Warum ich mich für ICloneable (d.h. manuell)
Herr Venkat Subramaniam (überflüssiger Link hier) erklärt ausführlich, warum .
Sein ganzer Artikel dreht sich um ein Beispiel, das versucht, für die meisten Fälle anwendbar zu sein, unter Verwendung von 3 Objekten: Person , Gehirn y Stadt . Wir wollen eine Person klonen, die ihr eigenes Gehirn, aber dieselbe Stadt hat. Sie können sich entweder alle Probleme vorstellen, die eine der oben genannten Methoden mit sich bringen kann, oder den Artikel lesen.
Dies ist meine leicht veränderte Version seiner Schlussfolgerung:
Kopieren eines Objekts durch Angabe von New
gefolgt vom Klassennamen führt oft zu Code, der nicht erweiterbar ist. Die Verwendung von clone, der Anwendung des Prototypenmusters, ist ein besserer Weg, dies zu erreichen. Allerdings kann die Verwendung von clone, wie sie in C# (und Java) vorgesehen ist, auch ziemlich problematisch sein. Es ist besser, einen geschützten (nicht-öffentlichen) Kopierkonstruktor bereitzustellen und diesen von der clone-Methode aus aufzurufen. Dies gibt uns die Möglichkeit, die Aufgabe der Erstellung eines Objekts an eine Instanz einer Klasse selbst zu delegieren, wodurch die Erweiterbarkeit und auch die sichere Erstellung der Objekte mit dem geschützten Kopierkonstruktor gewährleistet wird.
Ich hoffe, dass diese Umsetzung Klarheit schaffen kann:
public class Person : ICloneable
{
private final Brain brain; // brain is final since I do not want
// any transplant on it once created!
private int age;
public Person(Brain aBrain, int theAge)
{
brain = aBrain;
age = theAge;
}
protected Person(Person another)
{
Brain refBrain = null;
try
{
refBrain = (Brain) another.brain.clone();
// You can set the brain in the constructor
}
catch(CloneNotSupportedException e) {}
brain = refBrain;
age = another.age;
}
public String toString()
{
return "This is person with " + brain;
// Not meant to sound rude as it reads!
}
public Object clone()
{
return new Person(this);
}
…
}
Betrachten wir nun eine Klasse, die von Person abgeleitet ist.
public class SkilledPerson extends Person
{
private String theSkills;
public SkilledPerson(Brain aBrain, int theAge, String skills)
{
super(aBrain, theAge);
theSkills = skills;
}
protected SkilledPerson(SkilledPerson another)
{
super(another);
theSkills = another.theSkills;
}
public Object clone()
{
return new SkilledPerson(this);
}
public String toString()
{
return "SkilledPerson: " + super.toString();
}
}
Sie können versuchen, den folgenden Code auszuführen:
public class User
{
public static void play(Person p)
{
Person another = (Person) p.clone();
System.out.println(p);
System.out.println(another);
}
public static void main(String[] args)
{
Person sam = new Person(new Brain(), 1);
play(sam);
SkilledPerson bob = new SkilledPerson(new SmarterBrain(), 1, "Writer");
play(bob);
}
}
Das Ergebnis wird sein:
This is person with Brain@1fcc69
This is person with Brain@253498
SkilledPerson: This is person with SmarterBrain@1fef6f
SkilledPerson: This is person with SmarterBrain@209f4e
Beachten Sie, dass der hier implementierte Klon eine korrekte Zählung der Objekte vornimmt, wenn wir die Anzahl der Objekte zählen.
110 Stimmen
Kann nützlich sein: "Warum ist das Kopieren eines Objekts eine schreckliche Sache?" agiledeveloper.com/articles/cloning072002.htm
2 Stimmen
stackoverflow.com/questions/8025890/ Eine andere Lösung...
27 Stimmen
Werfen Sie einen Blick auf AutoMapper
4 Stimmen
Deine Lösung ist viel komplexer, ich habe mich beim Lesen verlaufen... hehehe. Ich verwende eine DeepClone-Schnittstelle. public interface IDeepCloneable<T> { T DeepClone(); }
0 Stimmen
@Pedro77: Ein Anliegen, das ich habe
IDeepCloneable
ist, dass nicht alle Sammlungen von Verweisen auf Dinge, die tief geklont werden können, geklont werden sollten; das richtige Verhalten beim Klonen einerList<T>
hängt nicht nur vonT
sondern auch nach dem Zweck der Listen. Wenn keines der Elemente in den Listen jemals etwas ausgesetzt sein wird, das sie verändern könnte, wäre es besser, die Verweise direkt zu kopieren, selbst wenn die Elemente innerhalb der Listen geklont werden könnten.0 Stimmen
Diese Frage wird auch hier beantwortet stackoverflow.com/q/129389/235715
4 Stimmen
@Pedro77 -- Interessanterweise heißt es in dem Artikel am Ende, dass man eine
clone
Methode auf die Klasse anwenden und dann einen internen, privaten Konstruktor aufrufen, der anthis
. Kopieren ist also schrecklich [sic], aber sorgfältiges Kopieren (und der Artikel ist definitiv lesenswert) ist es nicht. ;^)0 Stimmen
Wenn Sie dies benötigen, haben Sie vielleicht eine falsche Implementierung. Und wenn Sie Dependency Injection verwenden, macht es überhaupt keinen Sinn.
0 Stimmen
Letztendlich sind diese Frage und alle Antworten ungefähr so nützlich wie "Wie programmiere ich eine Klasse?" Es gibt viele Antworten, aber es gibt keine einzige richtige Antwort, trotz Abstimmungen. Das heißt NICHT, dass keine Antwort nützlich ist oder dass die Frage nicht sinnvoll ist, aber man sollte sich vor polarisierenden Antworten hüten. Das größte Defizit ist hier die Betonung der Bereitstellung einer detaillierten Dokumentation und der Verantwortung des Benutzers/Implementierers einer Klasse für das Verständnis der Details jeder Kopieroperation.
0 Stimmen
Warum nicht einfach eine neue Instanz davon besorgen? Oder wenn Sie ein Objekt kopieren wollen, das Sie geändert haben, anstatt es nur zu instanziieren, können Sie auch eine Methode erstellen, die all das tut, und diese Methode einfach zweimal aufrufen.
0 Stimmen
Rufen Sie die MemberwiseClone-Methode auf, um eine oberflächliche Kopie eines Objekts zu erstellen, und weisen Sie dann allen Eigenschaften oder Feldern, deren Werte Referenztypen sind, neue Objekte zu, deren Werte mit denen des Originalobjekts übereinstimmen. Die DeepCopy-Methode im Beispiel veranschaulicht diesen Ansatz. msdn.microsoft.com/de-us/library/
0 Stimmen
Prüfen Sie dies Antwort : stackoverflow.com/a/52097307/4707576 über: Klonen von Objekten ohne Serialisierung