2009-04-10 39 views
5

Tôi đang cố gắng tìm ra cách tốt nhất để lưu (serialize) và sau đó mở (deserialize) một cấu trúc cây. Cấu trúc của tôi được tạo thành từ nhiều loại đối tượng khác nhau với các thuộc tính khác nhau, nhưng mỗi thuộc tính được thừa kế từ lớp "Node" trừu tượng cơ bản.Serialization/Derialization của một cấu trúc cây

Mỗi nút có ID duy nhất (GUID) và có phương thức AddSuperNode (Node nd) sẽ đặt cha mẹ của nút. Điều này lần lượt gọi các phương thức khác cho phép nút cha để biết các nút con nào có nó. Tuy nhiên, một số nút cũng sử dụng phương thức AddAuxSuperNode() để thêm một phụ huynh thứ cấp vào Nút.

Tôi đã sử dụng tính năng tuần tự hóa nhị phân, nhưng giờ tôi nghĩ mình muốn sử dụng thứ gì đó mà tôi có nhiều quyền kiểm soát hơn và dữ liệu được tuần tự hóa dễ truy cập hơn. Tôi cũng muốn giữ lại thông tin Loại khi tôi deserialize, và có thể serialize giá trị tư nhân. Vì vậy, DataContractSerializer có vẻ như là cách tốt nhất để đi.

Tôi không thể chỉ cần serialize gốc Node trực tiếp vì các nút có nhiều cha mẹ. Tôi không muốn tạo các đối tượng trùng lặp. Vì vậy, nó có vẻ như tôi cần phải deconstruct cây vào một danh sách phẳng, và sau đó serialize đó. Sau đó, sau khi serializing danh sách đó tái tạo lại cây. Điều này có đúng không?

Giống như tôi đã nói trước mỗi Nút có mã định danh GUID duy nhất, nhưng ngay bây giờ các nút tham chiếu trực tiếp cha mẹ/con và không lưu trữ id của chúng. Tôi có thể cập nhật các phương thức AddSuperNode()AddAuxSuperNode() cũng cập nhật danh sách các id cha được tuần tự ngoài các tham chiếu trực tiếp. Nhưng tôi chỉ muốn cập nhật/tạo danh sách này khi đối tượng đang được tuần tự hóa. Vì vậy, tôi đã suy nghĩ tạo ra một phương pháp UpdateSuperNodeIDRefs() trong nút sẽ được gọi ngay trước khi tuần tự hóa.

Sau đây là những gì tôi định làm để tuần tự hóa và deserialization cấu trúc này. Bất cứ ai có thể gợi ý một cách tốt hơn/sạch hơn/hiệu quả hơn để làm điều này?

serialization

1) Cung cấp các nút gốc của cấu trúc cây

2) Phá vỡ cấu trúc cây vào một căn hộ điển (Guid id, Node nd) nơi idguid của nd.

3) Gọi UpdateSuperNodeIDRefs(); cho mỗi nút để cập nhật ID đã lưu cho cha mẹ của nó.

4) Serialize các điển các nút với DataContractSerializer

Deserialization

1) Deserialize các điển các nút

2) Itterate qua từng Node trong số từ điển, kết nối lại với cha mẹ. Đối với bất kỳ ID Chánh lưu trữ tìm ra tương ứng Node (s) trong điển với phù hợp với ID (s) gọi AddSuperNode() hoặc AddAuxSuperNode() tái connnect nút để mẹ của nó (s)

3) Từ bất kỳ Node trong từ điển tìm ra gốc rễ của cấu trúc

4) Return gốc Node

Trả lời

10

Nếu một nút có nhiều bố mẹ, thế thì nó không phải là cây; nó có lẽ là đồ thị . Tuy nhiên - lo lắng không; DataContractSerializer có thể xử lý việc này cho bạn:

using System; 
using System.IO; 
using System.Runtime.Serialization; 

[DataContract] 
class Node { 
    [DataMember] 
    public Node AnotherNode { get; set; } 
} 

static class Program 
{ 
    static void Main() 
    { 
     Node a = new Node(), b = new Node(); 
     // make it a cyclic graph, to prove reference-mode 
     a.AnotherNode = b; 
     b.AnotherNode = a; 

     // the preserveObjectReferences argument is the interesting one here... 
     DataContractSerializer dcs = new DataContractSerializer(
      typeof(Node), null, int.MaxValue, false, true, null); 
     using (MemoryStream ms = new MemoryStream()) 
     { 
      dcs.WriteObject(ms, a); 
      ms.Position = 0; 
      Node c = (Node) dcs.ReadObject(ms); 
      // so .AnotherNode.Another node should be back to "c" 
      Console.WriteLine(ReferenceEquals(c, c.AnotherNode.AnotherNode)); 
     } 

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