2009-03-25 69 views
5

Cách tốt nhất để sâu sao chép một tập hợp các đối tượng được kết nối với nhau? Ví dụ:Làm thế nào để sao chép các đối tượng liên kết sâu trong C#?

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

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

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

Các điều hiển nhiên phải làm là đi bộ các đối tượng và sâu bản sao tất cả mọi thứ như tôi đến với nó. Tuy nhiên, điều này tạo ra sự cố - nếu tôi sao chép một số A có chứa một số BB cũng nằm trong số Container, thì B sẽ được sao chép hai lần sau khi tôi sao chép Container.

Bước hợp lý tiếp theo là tạo Dictionary và tra cứu mọi đối tượng trước khi sao chép nó. Điều này có vẻ như nó có thể là một giải pháp chậm và không có hiệu quả, tuy nhiên.

Mọi suy nghĩ?

+0

dưới đây là cách tôi thực hiện: http://valueinjecter.codeplex.com/wikipage?title=Deep%20Cloning&referringTitle=Home – Omu

Trả lời

2

Đó không phải là giải pháp thanh lịch chắc chắn, nhưng việc sử dụng từ điển (hoặc hashmap) là không phổ biến. Một trong những lợi ích là một hashmap có một thời gian tra cứu liên tục, vì vậy tốc độ không thực sự đau khổ ở đây.

2

Giải pháp từ điển bạn đề xuất là tốt nhất mà tôi biết. Để tối ưu hóa hơn nữa, bạn có thể sử dụng object.GetHashCode() để nhận một băm cho đối tượng và sử dụng nó làm khóa từ điển. Nên nhanh chóng trừ khi bạn đang nói về cây đối tượng khổng lồ (10 đến 100 của hàng ngàn đối tượng).

2

Không phải là tôi quen thuộc với C#, nhưng thường là bất kỳ loại thu thập dữ liệu nào của một biểu đồ cho một số loại xử lý sẽ yêu cầu bảng tra cứu ngừng xử lý đối tượng do tham chiếu tuần hoàn. Vì vậy, tôi sẽ nghĩ rằng bạn sẽ cần phải làm như vậy ở đây.

0

có thể tạo cờ bit để cho biết liệu đối tượng này đã được sao chép trước đó chưa.

0

Một giải pháp có thể khác mà bạn có thể điều tra là tuần tự hóa các đối tượng thành một luồng và sau đó tạo lại chúng từ cùng một luồng đó thành các phiên bản mới. Điều này thường làm việc kỳ diệu khi mọi thứ khác dường như quá phức tạp và lộn xộn.

Marc

+0

Bạn có thể xây dựng không? Làm thế nào tôi có thể ngăn ngừa serialiizing cùng một đối tượng hai lần? Hoặc nếu tôi chỉ serialize "Container", làm thế nào tôi có thể lưu trữ * tài liệu tham khảo * để A và B thay vì toàn bộ đối tượng, để tránh trùng lặp? Tôi không thể chỉ sử dụng một chỉ mục đơn giản như bạn sẽ tin từ ví dụ đơn giản. – zildjohn01

+0

WCF hỗ trợ điều này với một số tinh chỉnh (http://blogs.msdn.com/sowmy/archive/2006/03/26/561188.aspx). Nhưng serialization, trong khi nhanh chóng để mã, sẽ thực hiện tồi tệ hơn nhiều so với một bản sao sâu rõ ràng. –

+0

True - serializing và deserializing một lần nữa có thể không được đầu về hiệu suất. Điều này đi xuống để đời đời "nó phụ thuộc" kịch bản :-) Bạn có cần hiệu suất hàng đầu và bạn làm điều này hàng trăm ngàn lần trong một vòng lặp -> sau đó serializing có thể không phải là con đường tốt nhất để có. –

Các vấn đề liên quan