2009-05-04 49 views
8

我有2個接口IA和IB。如何序列化具有接口作爲屬性的對象?

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

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

    void SetIA(IA value); 
} 

每個接口引用另一個接口。

我想按照下面的定義序列化ClassA。

[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; 
    } 
} 

當我嘗試太序列化時,我得到一個錯誤,因爲2個屬性是接口。我想序列化屬性。

我該如何解決這個問題?

我需要在每個接口中引用另一個接口。而且我需要能夠來回地序列化課程。

回答

10

你在代碼中有各種錯誤,否則這將工作得很好。

  1. ClassA的構造函數中,您正在設置局部變量IB,而不是對象的IB對象。
  2. ClassB中,您將轉回到對象具體類,而不是將其作爲接口類型單獨保留。

這裏是你的代碼應該是什麼樣子:

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

我修復了錯誤,它能夠來回移動。 – 2009-05-04 20:31:50

+0

是的。很容易出現複製粘貼錯誤。很高興這有助於。 – 2009-05-04 20:40:57

0

假設你不想序列化的接口屬性,放置在接口屬性如下屬性

[NonSerialized] 

+1

我想序列化的屬性。我已經重新提出了這個問題來反映這一點。 – 2009-05-04 20:13:05

+0

你可以用一個自定義的序列化器/解串器來做到這一點。在您的自定義序列化器中,您只需維護關於保存在接口屬性中的對象的附加信息。 你也可以避免通過簡單計數已經序列化/反序列化的循環引用。 – rein 2009-05-04 20:25:40

0

爲了回答你的問題:還有兩個問題。你是什​​麼序列化?數據庫引用是否可識別?

您不序列化接口;你序列化對象。您序列化的對象是IA或IB的實現。

由序列化對象決定是否應該序列化其中一個屬性。如果屬性需要序列化,它應該實現Serializable接口。

如果數據庫能夠識別序列化對象,那麼您只能序列化由循環引用A < - > B形成的所謂「島」:它應該首先爲A分配空間,開始序列化A的屬性。當它到達B時,它會發現它的一個屬性是指A。序列化應包含對A的序列化版本的引用。

這很像兩個熟人在同一時間搬家:首先他們會交換他們未來的地址,只有這樣他們纔會身體上移動。

2

你的對象實現了ISerializable來控制序列化。

[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); 
    } 
} 
-1

接口屬性不可序列化。但是,引用這些屬性的字段(在子類中)是。

你需要做這樣的事情:

[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; 
    } 
} 
相關問題