Tôi cần phải thực hiện nhân bản sâu trên mô hình đối tượng phức tạp của mình. Bạn nghĩ gì là cách tốt nhất để làm điều đó trong .Net?
Tôi nghĩ về việc sắp xếp/Deserializing
không cần phải đề cập rằng MemberwiseClone
là không đủ tốt.. Net Nhân bản sâu - cách tốt nhất để làm điều đó là gì?
Trả lời
Cách tốt nhất có thể là triển khai giao diện System.IClonable trong đối tượng của bạn và tất cả các trường của nó cũng cần các khả năng nhân bản sâu tùy chỉnh. Sau đó, bạn triển khai phương thức Clone để trả về bản sao sâu của đối tượng và thành viên của đối tượng.
Vẫn còn các đề xuất chống lại điều này và Tôi đồng ý với họ.IClonable trên một đối tượng có thể có nghĩa là sâu, trong khi trên một đối tượng khác là nông cạn. Không có cách nào để phân biệt khi thực hiện cuộc gọi. Tất nhiên, điều này thực sự không hoàn toàn áp dụng cho một dự án nội bộ, nhưng không phải là một thực tế tồi để nhận ra sớm. – jfsk3
IClonable không hoạt động đối với các đối tượng phức tạp. –
Nếu bạn kiểm soát mô hình đối tượng, sau đó bạn có thể viết mã để làm điều đó, nhưng nó là rất nhiều bảo trì. Tuy nhiên, có rất nhiều vấn đề, có nghĩa là trừ khi bạn cần hoàn toàn hiệu suất nhanh nhất, sau đó việc tuần tự hóa thường là câu trả lời dễ quản lý nhất.
Đây là một trong những trường hợp mà BinaryFormatter
hoạt động được chấp nhận; bình thường tôi không phải là một fan (do các vấn đề với versioning, vv) - nhưng vì dữ liệu tuần tự là để tiêu thụ ngay lập tức, đây không phải là vấn đề.
Nếu bạn muốn nhanh hơn một chút (nhưng không có mã của riêng bạn), thì protobuf-net
có thể hữu ích, nhưng yêu cầu thay đổi mã (để thêm siêu dữ liệu cần thiết, v.v.). Và nó là dựa trên cây (không dựa trên đồ thị).
serializers Khác (XmlSerializer
, DataContractSerializer
) cũng là tốt, nhưng nếu nó là chỉ cho clone, họ có thể không cung cấp nhiều hơn BinaryFormatter
(ngoại trừ có lẽ rằng XmlSerializer
không cần [Serializable]
.
Vì vậy, thực sự, nó phụ thuộc vào các lớp học chính xác của bạn và kịch bản.
Có lẽ một liên kết đến ví dụ có thể là tốt đẹp. Im sử dụng UWP và tôi không thể sử dụng BinaryFormatter. Trình tuần tự hóa XML được đưa ra dưới đây bởi Marty. Tôi tò mò về DataContractSerializer và protobuf-net. –
bạn có thể thử AltSerialize mà trong nhiều trường hợp là nhanh hơn so với serializer Net. nó cũng cung cấp bộ nhớ đệm và tùy chỉnh các thuộc tính để tăng tốc độ tuần tự.
Ví dụ về nhân bản sâu sắc từ tạp chí 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));
}
Nếu bạn đang chạy mã trong một môi trường tin cậy phần như Rackspace đám mây, bạn sẽ có khả năng bị hạn chế từ việc sử dụng BinaryFormatter. XmlSerializer có thể được sử dụng thay thế.
public static T DeepClone<T>(T obj)
{
using (var ms = new MemoryStream())
{
XmlSerializer xs = new XmlSerializer(typeof(T));
xs.Serialize(ms, obj);
ms.Position = 0;
return (T)xs.Deserialize(ms);
}
}
Không hoạt động khi một số thuộc tính của đối tượng nhân bản là giao diện (ví dụ: IEnumerable, IList, v.v.). Ném một ngoại lệ. –
Hãy xem bài viết thực sự tốt C# Object Clone Wars. Tôi đã tìm thấy một giải pháp rất quan tâm ở đó: Copyable: A framework for copying or cloning .NET objects
Cách tốt nhất để thực hiện thủ công điều này. Nó sẽ thực sự nhanh hơn bất kỳ phương pháp chung nào khác. Ngoài ra, có rất nhiều thư viện cho hoạt động này (Bạn có thể thấy một số danh sách với các tiêu chí hiệu suất here).
Nhân tiện, BinaryFormatter rất chậm cho tác vụ này và chỉ có thể tốt để thử nghiệm.
- 1. Twisted + SQLAlchemy và cách tốt nhất để làm điều đó
- 2. Cách tốt nhất để tăng một điều tra là gì?
- 3. Thuật toán tạo bản đồ độ sâu tốt nhất là gì?
- 4. Cách tốt nhất để tích hợp điều khiển phiên bản TFS là gì
- 5. Cách tốt nhất để sao chép/sao chép sâu một từ điển .NET chung là gì <string, T>?
- 6. Cách tốt nhất để nhân bản/sao chép một Observablearray trong knockoutJS là gì?
- 7. Cách tốt nhất để thay thế văn bản trong Tệp bằng C#/.NET là gì?
- 8. Cách tốt nhất để sao chép sâu một băm băm trong Perl là gì?
- 9. Cách tốt nhất để làm điều gì đó định kỳ trong Erlang?
- 10. Cách tốt nhất để nhân bản các quan sát?
- 11. Cách tốt nhất để tạo bản sao sâu của cấu trúc dữ liệu trong Perl là gì?
- 12. Hệ thống xếp hàng - cách tốt nhất để bắt đầu nhiều công nhân là gì?
- 13. Các tùy chọn tốt nhất hiện tại để song song ứng dụng .NET chuyên sâu CPU là gì?
- 14. Kiểm tra đơn vị để nhân bản sâu
- 15. Cách tốt nhất để cập nhật điều khiển biểu mẫu từ chuỗi công việc là gì?
- 16. Cách tốt nhất để bố trí lớp C# là gì?
- 17. Nhân bản sâu so với cài đặt của innerHTML: nhanh hơn là gì?
- 18. Cách tốt nhất để lưu cài đặt người dùng cho ứng dụng .NET là gì?
- 19. Làm sạch chuỗi? là có cách nào tốt hơn để làm điều đó?
- 20. Cách tốt nhất để có được đường dẫn exe thực thi trong .NET là gì?
- 21. Cách tốt nhất để tạo và in hóa đơn trong ứng dụng .NET là gì?
- 22. Cách tốt nhất để sử dụng các lớp .NET từ Visual Basic 6 là gì?
- 23. Cách tốt nhất để tổ chức quy trình công nhân trong Rails là gì?
- 24. Cách tốt nhất để lưu trữ chuỗi kết nối trong .NET DLLs là gì?
- 25. Cách tốt nhất để quản lý cây phụ thuộc trong .NET là gì?
- 26. Cách tốt nhất để gửi email từ ứng dụng .NET là gì?
- 27. Cách tốt nhất để ghi lại mã f # là gì?
- 28. Triển khai tốt nhất cho AOP trong .Net là gì?
- 29. Cách tốt nhất để kết hợp đường dẫn và tên tệp trong C# /. NET là gì?
- 30. Cách tốt nhất để phân tích một thuộc tính boolean XML (trong .NET) là gì?
Hãy thực sự cẩn thận; đây có phải là điều bạn thực sự muốn nói không? Thông tư tham chiếu giữa các đối tượng có thể nhanh chóng gây ra các vấn đề với nhân bản sâu. –
điều này thực hiện mà không cần serialization http://valueinjecter.codeplex.com/wikipage?title=Deep%20Cloning&referringTitle=Home – Omu
UltraMapper https://www.nuget.org/packages/UltraMapper/ – sam