Die generischen Ansätze sind alle technisch gültig, aber ich wollte nur eine Anmerkung von mir selbst hinzufügen, da wir selten tatsächlich eine echte tiefe Kopie benötigen, und ich würde stark gegen die Verwendung von generischen tiefes Kopieren in tatsächlichen Geschäftsanwendungen, da das macht es, so dass Sie viele Orte, wo die Objekte kopiert und dann explizit geändert werden, seine leicht zu verlieren haben könnte.
In den meisten realen Situationen möchten Sie auch so viel granulare Kontrolle über den Kopierprozess wie möglich haben, da Sie nicht nur an das Datenzugriffs-Framework gekoppelt sind, sondern auch in der Praxis die kopierten Geschäftsobjekte selten zu 100 % gleich sein sollten. Denken Sie zum Beispiel an die Referenz-IDs, die vom ORM zur Identifizierung von Objektreferenzen verwendet werden. Eine vollständige Deep Copy kopiert auch diese IDs, so dass die Objekte zwar im Speicher unterschiedlich sind, aber sobald Sie sie an den Datenspeicher übermitteln, werden sie sich beschweren, so dass Sie diese Eigenschaften nach dem Kopieren ohnehin manuell ändern müssen.
Erweiternd auf @cregox Antwort mit ICloneable, was ist eigentlich eine tiefe Kopie? Es ist nur ein neu zugewiesenes Objekt auf dem Heap, das mit dem ursprünglichen Objekt identisch ist, aber einen anderen Speicherplatz belegt. Warum also nicht einfach ein neues Objekt erstellen, anstatt eine generische Klon-Funktionalität zu verwenden?
Ich persönlich verwende die Idee der statischen Fabrikmethoden für meine Domänenobjekte.
Beispiel:
public class Client
{
public string Name { get; set; }
protected Client()
{
}
public static Client Clone(Client copiedClient)
{
return new Client
{
Name = copiedClient.Name
};
}
}
public class Shop
{
public string Name { get; set; }
public string Address { get; set; }
public ICollection<Client> Clients { get; set; }
public static Shop Clone(Shop copiedShop, string newAddress, ICollection<Client> clients)
{
var copiedClients = new List<Client>();
foreach (var client in copiedShop.Clients)
{
copiedClients.Add(Client.Clone(client));
}
return new Shop
{
Name = copiedShop.Name,
Address = newAddress,
Clients = copiedClients
};
}
}
Wenn jemand auf der Suche ist, wie er die Instanziierung von Objekten strukturieren kann, während er die volle Kontrolle über den Kopierprozess behält, ist das eine Lösung, mit der ich persönlich sehr erfolgreich war. Die geschützten Konstruktoren machen es auch möglich, dass andere Entwickler gezwungen sind, die Factory-Methoden zu verwenden, was einen sauberen einzigen Punkt der Objektinstanziierung ergibt, der die Konstruktionslogik innerhalb des Objekts kapselt. Man kann die Methode auch überladen und mehrere Klon-Logiken für verschiedene Stellen haben, falls nötig.
112 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...
28 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