2009-05-04 42 views
8

Tôi có 2 giao diện IA và IB.Làm cách nào để tuần tự hóa một đối tượng có giao diện là thuộc tính?

public interface IA 
{ 
    IB InterfaceB { get; set; } 
} 

public interface IB 
{ 
    IA InterfaceA { get; set; } 

    void SetIA(IA value); 
} 

Mỗi giao diện tham chiếu đến nhau.

Tôi đang cố gắng tuần tự hóa ClassA như được định nghĩa bên dưới.

[Serializable] 
public class ClassA : IA 
{ 
    public IB InterfaceB { get; set; } 

    public ClassA() 
    { 
     // Call outside function to get Interface B 
     IB interfaceB = Program.GetInsanceForIB(); 

     // Set IB to have A 
     interfaceB.SetIA(this); 
    } 
} 

[Serializable] 
public class ClassB : IB 
{ 
    public IA InterfaceA { get; set; } 

    public void SetIA(IA value) 
    { 
     this.InterfaceA = value as ClassA; 
    } 
} 

Tôi gặp lỗi khi thử quá theo thứ tự vì 2 thuộc tính là giao diện. Tôi muốn tuần tự hóa các thuộc tính.

Làm cách nào để giải quyết vấn đề này?

Tôi cần phải có tham chiếu trong mỗi giao diện cho giao diện khác. Và tôi cần để có thể sắp xếp lại lớp học qua lại.

Trả lời

10

Bạn có nhiều lỗi khác nhau trong mã của mình, nếu không điều này sẽ hoạt động tốt.

  1. Trong hàm tạo cho ClassA, bạn đang đặt biến cục bộ IB, không phải đối tượng IB của đối tượng.
  2. Trong ClassB, bạn sẽ truyền trở lại lớp bê tông đối tượng, thay vì để nó một mình làm loại giao diện.

Đây là những gì mã của bạn sẽ giống như thế:

public interface IA 
{ 
    IB InterfaceB { get; set; } 
} 

public interface IB 
{ 
    IA InterfaceA { get; set; } 
    void SetIA(IA value); 
} 

[Serializable] 
public class ClassA : IA 
{  
    public IB InterfaceB { get; set; }  

    public ClassA()  
    {   
     // Call outside function to get Interface B   
     this.InterfaceB = new ClassB(); 

     // Set IB to have A   
     InterfaceB.SetIA(this);  
    } 
} 

[Serializable] 
public class ClassB : IB 
{  
    public IA InterfaceA { get; set; }  

    public void SetIA(IA value)  
    {  
     this.InterfaceA = value;  
    } 
} 

[STAThread] 
static void Main() 
{ 
    MemoryStream ms = new MemoryStream(); 
    BinaryFormatter bin = new BinaryFormatter(); 

    ClassA myA = new ClassA(); 

    bin.Serialize(ms, myA); 

    ms.Position = 0; 

    ClassA myOtherA = bin.Deserialize(ms) as ClassA; 


    Console.ReadLine(); 
} 
+0

Tôi đã sửa lỗi và nó có thể đi qua lại. –

+0

Vâng. Thật dễ dàng để có được các lỗi sao chép-dán. Vui mừng điều này đã giúp. –

0

Giả sử bạn không muốn serialize tài sản giao diện, đặt các thuộc tính sau

[NonSerialized] 

về quyền sở hữu giao diện.

+1

Tôi muốn sắp đặt các thuộc tính. Tôi đã viết lại câu hỏi để phản ánh điều đó. –

+0

Bạn có thể thực hiện việc này bằng bộ chỉnh sửa/trình chỉnh sửa tùy chỉnh. Trong serializer tùy chỉnh của bạn, bạn chỉ cần duy trì thông tin bổ sung về đối tượng được giữ trong thuộc tính giao diện. Bạn cũng có thể tránh tham chiếu vòng tròn mà không nghi ngờ gì bằng cách duy trì một số đơn giản về những gì bạn đã sắp xếp/deserialized rồi. – rein

0

Đổi lại câu hỏi của bạn: hai câu hỏi khác. Bạn làm gì? Là cơ sở dữ liệu tham khảo-nhận thức?

Bạn không serialize giao diện; bạn sắp xếp các đối tượng. Đối tượng bạn sắp xếp thứ tự là triển khai IA hoặc IB.

Tùy thuộc vào đối tượng được tuần tự hóa để quyết định xem một trong các thuộc tính của nó có được tuần tự hay không. Nếu thuộc tính không cần tuần tự hóa, nó sẽ triển khai giao diện Serializable.

Bạn chỉ có thể tuần tự hóa một tên gọi là 'đảo' được tạo thành bởi tham chiếu vòng tròn A < -> B nếu cơ sở dữ liệu có thể xác định các đối tượng được tuần tự hóa: trước tiên phải phân bổ không gian cho A, bắt đầu tuần tự hóa các thuộc tính của A. Khi nó đến B, nó sẽ tìm thấy một trong những thuộc tính của nó đề cập đến A. Việc serialization sau đó nên bao gồm một tham chiếu đến phiên bản serialized của A.

Nó giống như hai người quen di chuyển nhà cùng một lúc: đầu tiên họ sẽ trao đổi địa chỉ tương lai của họ, chỉ sau đó họ sẽ di chuyển về thể chất.

2

Thực hiện ISerializable trên các đối tượng của bạn để kiểm soát serialization.

[Serializable] 
public class ClassB : IB, ISerializable 
{ 
    public IA InterfaceA { get; set; } 

    public void SetIA(IA value) 
    { 
    this.InterfaceA = value as ClassA; 
    } 

    private MyStringData(SerializationInfo si, StreamingContext ctx) { 
    Type interfaceAType = System.Type.GetType(si.GetString("InterfaceAType")); 
    this.InterfaceA = si.GetValue("InterfaceA", interfaceAType); 
    } 

    void GetObjectData(SerializationInfo info, StreamingContext ctx) { 
    info.AddValue("InterfaceAType", this.InterfaceA.GetType().FullName); 
    info.AddValue("InterfaceA", this.InterfaceA); 
    } 
} 
+0

Thay đổi đối với ClassA được để lại dưới dạng bài tập cho người đọc. :) Khá nhiều điều tương tự. – Greg

-1

Thuộc tính giao diện không thể tuần tự hóa được. Tuy nhiên, các trường tham chiếu đến các thuộc tính đó (trong lớp con) là.

Bạn sẽ cần phải làm một cái gì đó như thế này:

[Serializable] 
public class ClassA : IA 
{ 
    private IB _interfaceB; 
    public IB InterfaceB { get { return _interfaceB; } set { _interfaceB = value; } } 

    public ClassA() 
    { 
     // Call outside function to get Interface B 
     IB interfaceB = Program.GetInsanceForIB(); 

     // Set IB to have A 
     interfaceB.SetIA(this); 
    } 
} 

[Serializable] 
public class ClassB : IB 
{ 
    private IA _interfaceA; 
    public IA InterfaceA { get { return _interfaceA; } set { _interfaceA = value; } } 

    public void SetIA(IA value) 
    { 
     this.InterfaceA = value as ClassA; 
    } 
} 
+0

Tôi không gặp vấn đề gì khi sắp xếp đồ thị đối tượng. Nơi nào bạn nhận được rằng các thuộc tính giao diện không phải là serializable? Ngoài ra, tại sao có instace riêng khi tài sản tự động hoạt động tốt? –

+0

Rất tiếc. Điều này là do một sự hiểu lầm cơ bản (một phần của tôi) về những gì là và không phải là serializable. (Tôi đã làm nó sai tất cả cùng.) Giao diện không được serializable; các thuộc tính trong một lớp bắt nguồn từ một giao diện CÓ thể tuần tự hóa. Cảm ơn bạn đã chỉ ra điều đó. –

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