如何序列化具有接口作为属性的对象?

时间:2009-05-04 20:07:46

标签: c# serialization interface

我有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个属性是接口。我想序列化属性。

我如何解决这个问题?

我需要在每个接口中引用另一个接口。我需要能够来回序列化这个类。

5 个答案:

答案 0 :(得分:10)

您的代码中存在各种错误,否则这样可以正常工作。

  1. ClassA的构造函数中,您正在设置局部变量IB,而不是对象的IB对象。
  2. ClassB中,您将回退到对象具体类,而不是将其作为接口类型。
  3. 以下是您的代码应该是什么样的:

    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();
    }
    

答案 1 :(得分: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);
  }
}

答案 2 :(得分:0)

假设您不想序列化接口属性,请放置以下属性

[NonSerialized]

在接口属性上。

答案 3 :(得分:0)

作为回答你的问题:另外两个问题。你怎么序列化?数据库是否可识别引用?

您没有序列化接口;你序列化对象。您序列化的对象是IA或IB的实现。

由序列化对象决定是否应该序列化其中一个属性。如果属性 需要序列化,它应该实现Serializable接口。

您只能序列化由循环引用A< - >形成的所谓'岛'。 B如果数据库可以识别序列化对象:它应首先为A分配空间,开始序列化A的属性。当它到达B时,它会找到其中一个引用A的属性。序列化应该包含对A的序列化版本的引用。

这就像两个熟人在同一时间搬家一样:首先他们会交换未来的地址,然后他们才会搬家。

答案 4 :(得分:-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;
    }
}