2009-03-25 13 views
5

Jaki jest najlepszy sposób na głębokie klonowanie połączonego zestawu obiektów? Przykład:Jak głęboko klonować połączone obiekty w języku C#?

class A { 
    B theB; // optional 
    // ... 
} 

class B { 
    A theA; // optional 
    // ... 
} 

class Container { 
    A[] a; 
    B[] b; 
} 

Oczywistym wyjściem jest chodzenie po przedmiotach i głębokie klonowanie wszystkiego, kiedy do niego dojdę. Stwarza to jednak problem - jeśli sklonuję plik A, który zawiera B, i że B jest również w Container, to zostanie on sklonowany dwa razy po sklonowaniu Container.

Następnym logicznym krokiem jest stworzenie Dictionary i wyszukanie każdego obiektu przed jego sklonowaniem. Wygląda jednak na to, że może to być powolne i bezwstydne rozwiązanie.

Jakieś myśli?

+0

Oto jak to zrobić: http://valueinjecter.codeplex.com/wikipage?title=Deep%20Cloning&referringTitle=Home – Omu

Odpowiedz

2

Nie jest to na pewno eleganckie rozwiązanie, ale często zdarza się używać słownika (lub hashmap). Jedną z korzyści jest to, że hashmap ma stały czas wyszukiwania, więc prędkość naprawdę nie cierpi.

2

Proponowane przez ciebie słownictwo jest najlepsze, jakie znam. Aby zoptymalizować dalej, możesz użyć object.GetHashCode(), aby uzyskać skrót dla obiektu i użyć go jako klucza słownika. Powinieneś być szybki, chyba że mówisz o dużych drzewach obiektów (od 10 do 100 tysięcy obiektów).

2

Nie dlatego, że jestem zaznajomiony z C#, ale zazwyczaj każdy typ przeszukiwania wykresu dla pewnego rodzaju przetwarzania będzie wymagał tabeli odnośnika, aby zatrzymać przetwarzanie obiektu z powodu cyklicznych odniesień. Więc sądzę, że będziesz musiał zrobić to samo tutaj.

0

może utworzyć flagę bitową wskazującą, czy obiekt ten został wcześniej sklonowany.

0

Innym możliwym rozwiązaniem, które można zbadać, jest serializowanie obiektów do strumienia, a następnie rekonstrukcja ich z tego samego strumienia w nowe instancje. To często działa cuda, gdy wszystko inne wydaje się strasznie zawiłe i niechlujny.

Marc

+0

Czy możesz rozwinąć? Jak mogłem zapobiec dwukrotnemu serializowaniu tego samego obiektu? A może po prostu serializować "Kontener", jak mogę przechowywać * referencje * do A i B zamiast całego obiektu, aby uniknąć powielania? Nie mogę po prostu użyć prostego indeksu, tak jak na podstawie tego prostego przykładu. – zildjohn01

+0

WCF obsługuje to z pewnymi zmianami (http://blogs.msdn.com/sowmy/archive/2006/03/26/561188.aspx). Ale serializacja, choć szybka do kodu, będzie działała znacznie gorzej niż wyraźna, głęboka kopia. –

+0

True - ponowne szeregowanie i deserializacja może nie być najlepsza pod względem wydajności. Sprowadza się to do wiecznego scenariusza "to zależy" :-) Czy potrzebujesz najwyższej wydajności i robisz to setki tysięcy razy w pętli -> wtedy serializacja może nie być najlepszą drogą do wykonania. –

Powiązane problemy