繁体   English   中英

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

[英]How can I serialize an object that has an interface as a property?

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

我怎么能绕过这个?

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

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

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

在对象上实现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);
  }
}

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

[NonSerialized]

在接口属性上。

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

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

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

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

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

接口属性不可序列化。 但是,引用这些属性的字段(在子类中)是。

你需要做这样的事情:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM