Muszę wykonać głębokie klonowanie mojego złożonego modelu obiektu. Jak myślisz, co jest najlepszym sposobem na to w .Net?
Myślałem o serializowaniu/Deserializowaniu
nie trzeba wspominać, że MemberwiseClone
nie jest wystarczająco dobre..Net Głębokie klonowanie - jaki jest najlepszy sposób na zrobienie tego?
Odpowiedz
Najlepszym sposobem jest prawdopodobnie wdrożenie interfejsu System.IClonable w obiekcie i we wszystkich jego polach, które również wymagają niestandardowych funkcji głębokiego klonowania. Następnie zaimplementuj metodę Clone, aby zwrócić głęboką kopię obiektu i jego członków.
Nadal istnieją zalecenia przeciw temu i Zgadzam się z nimi.ICONowalne na jednym obiekcie może oznaczać głębokie, podczas gdy na innym jest płytkie. Nie ma sposobu, aby rozróżnić podczas wykonywania połączenia. Oczywiście nie jest to całkowicie możliwe do zastosowania w projekcie wewnętrznym, ale nie jest to zła praktyka, którą należy wcześnie rozpoznać. – jfsk3
IClonable nie działa dla złożonych obiektów. –
Jeśli kontrolujesz model obiektu, możesz napisać kod, aby to zrobić, ale wymaga to wielu czynności konserwacyjnych. Istnieje jednak wiele problemów, które oznaczają, że chyba najbardziej potrzebna jest maksymalna wydajność, a następnie serializacja jest często najłatwiejszą do rozwiązania odpowiedzią.
Jest to jeden z przypadków, w których BinaryFormatter
działa akceptowalnie; zwykle nie jestem fanem (ze względu na problemy z wersjonowaniem itp.) - ale ponieważ zserializowane dane są przeznaczone do natychmiastowej konsumpcji, nie jest to problemem.
Jeśli chcesz go nieco szybciej (ale bez własnego kodu), to może pomóc protobuf-net
, ale wymaga zmian kodu (aby dodać niezbędne metadane itp.). Jest oparty na drzewach (nie na grafach).
Inne serializers (XmlSerializer
, DataContractSerializer
) także są w porządku, ale jeśli jest tylko dla klonu, mogą one nie oferują znacznie ponad BinaryFormatter
(może z wyjątkiem tego XmlSerializer
nie potrzebuje [Serializable]
.
Tak naprawdę, to zależy od dokładnych klas i scenariusza.
Być może link do przykładu może być miły. Im przy użyciu UWP i nie mogę używać BinaryFormatter. Serializator XML jest podany poniżej przez Marty'ego. Interesuje mnie DataContractSerializer i protobuf-net. –
można spróbować AltSerialize co w wielu przypadkach jest szybszy niż serializatora .NET. zapewnia również buforowanie i atrybutów niestandardowych, aby przyspieszyć serializacji.
Przykład głębokim klonowanie z magazynu MSDN:
Object DeepClone(Object original)
{
// Construct a temporary memory stream
MemoryStream stream = new MemoryStream();
// Construct a serialization formatter that does all the hard work
BinaryFormatter formatter = new BinaryFormatter();
// This line is explained in the "Streaming Contexts" section
formatter.Context = new StreamingContext(StreamingContextStates.Clone);
// Serialize the object graph into the memory stream
formatter.Serialize(stream, original);
// Seek back to the start of the memory stream before deserializing
stream.Position = 0;
// Deserialize the graph into a new set of objects
// and return the root of the graph (deep copy) to the caller
return (formatter.Deserialize(stream));
}
Jeśli używasz kodu w częściowym środowiska Powierniczego takich jak Rackspace Cloud, będzie prawdopodobnie ograniczony z użyciem BinaryFormatter. Zamiast tego można użyć XmlSerializer.
Nie działa, gdy niektóre właściwości sklonowanego obiektu są interfejsami (np. IEnumerable, IList itp.). Zgłasza wyjątek. –
Proszę spojrzeć na naprawdę dobry artykuł C# Object Clone Wars. Znalazłem tam bardzo interesujące rozwiązanie: Copyable: A framework for copying or cloning .NET objects
Najlepszym sposobem na wdrożenie tego ręcznie. Będzie to naprawdę szybsze niż jakiekolwiek inne ogólne metody. Ponadto istnieje wiele bibliotek dla tej operacji (możesz zobaczyć listę z testami wydajności here).
Nawiasem mówiąc, BinaryFormatter jest bardzo powolny dla tego zadania i może być dobry tylko do testowania.
- 1. Najlepszy sposób na zrobienie tego rodzaju cienia?
- 2. Twisted + SQLAlchemy i najlepszy sposób na zrobienie tego
- 3. Object.isArray() jest powolny, czy istnieje szybki sposób na zrobienie tego?
- 4. Jaki jest najlepszy sposób na seed srand()?
- 5. Jaki jest najlepszy sposób na wdrożenie "timera"?
- 6. Jaki jest najlepszy sposób na głębokie kopiowanie mieszania haszy w Perlu?
- 7. Jaki jest najlepszy sposób na klonowanie/duplikowanie projektu do nowego z git?
- 8. Jaki jest najlepszy sposób na skopiowanie listy?
- 9. Jaki jest najlepszy sposób na naukę Erlanga?
- 10. Jaki jest najlepszy sposób na naukę CUDA?
- 11. Jak uniknąć tego błędu piklowania i jaki jest najlepszy sposób na zrównoleglenie tego kodu w Pythonie?
- 12. Jaki jest najlepszy sposób obracania punktu CGPoint na siatce?
- 13. Jaki jest najlepszy sposób zarządzania drzewem zależności w .NET?
- 14. jaki jest najlepszy sposób zastosowania maski do EditText na Androida?
- 15. Jaki jest najlepszy sposób serializacji jSON .NET DataTable w WCF?
- 16. Jaki jest najlepszy sposób obliczenia rozmiaru katalogu w VB .NET?
- 17. Jaki jest najlepszy sposób na uzyskanie liczb losowych w NumPy?
- 18. Jaki jest najlepszy sposób na porównywanie programów w systemie Windows?
- 19. Jaki jest najlepszy sposób na analizowanie strony internetowej w Ruby?
- 20. Jaki jest najlepszy sposób na przechowywanie i pobieranie wielowymiarowych NSMutableArrays?
- 21. Jaki jest najlepszy sposób na matematykę z CGFloats w szybkim?
- 22. Jaki jest najlepszy sposób bezpiecznego publikowania postu na stronie?
- 23. QAbstractItemModel foreach iterator z funktorami: czy jest lepszy sposób na zrobienie tego?
- 24. jaki jest najlepszy sposób na kodowanie ciągu wieloliniowego?
- 25. Jaki jest najlepszy sposób profilowania wykonywania javascript?
- 26. Jaki jest najlepszy sposób na uzyskanie równoległej nieskończonej pętli?
- 27. Jaki jest najlepszy sposób obsługi wielu działań?
- 28. Jaki jest najlepszy sposób zapisu do pliku w Ruby?
- 29. Najlepszy sposób na randkę z .NET?
- 30. Jaki jest najlepszy sposób wykonywania jQuery .change()
Bądź naprawdę ostrożny; czy to naprawdę masz na myśli? Okrężne odniesienia między obiektami mogą szybko powodować problemy z głębokim klonowaniem. –
robi to bez serializacji http://valueinjecter.codeplex.com/wikipage?title=Deep%20Cloning&referringTitle=Home – Omu
UltraMapper https://www.nuget.org/packages/UltraMapper/ – sam