C# 9.0 führt die with
Schlüsselwort, das ein record
(Danke Mark Nading). Dies sollte sehr einfaches Klonen von Objekten (und Mutation, falls erforderlich) mit sehr wenig Boilerplate ermöglichen, aber nur mit einer record
.
Es scheint nicht möglich zu sein, eine Klasse (nach Wert) zu klonen, indem man sie in eine generische record
;
using System;
public class Program
{
public class Example
{
public string A { get; set; }
}
public record ClonerRecord<T>(T a)
{
}
public static void Main()
{
var foo = new Example {A = "Hello World"};
var bar = (new ClonerRecord<Example>(foo) with {}).a;
foo.A = "Goodbye World :(";
Console.WriteLine(bar.A);
}
}
Dies schreibt "Goodbye World :(" - die Zeichenkette wurde per Referenz kopiert (unerwünscht). https://dotnetfiddle.net/w3IJgG
(Unglaublicherweise funktioniert das oben Gesagte korrekt mit einer struct
! https://dotnetfiddle.net/469NJv )
Aber das Klonen eines record
scheint wie eingerückt zu funktionieren, Klonen nach Wert.
using System;
public class Program
{
public record Example
{
public string A { get; set; }
}
public static void Main()
{
var foo = new Example {A = "Hello World"};
var bar = foo with {};
foo.A = "Goodbye World :(";
Console.WriteLine(bar.A);
}
}
Dies ergibt "Hello World", die Zeichenkette wurde nach Wert kopiert! https://dotnetfiddle.net/MCHGEL
Weitere Informationen finden Sie in diesem Blogbeitrag:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/with-expression
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