简体   繁体   English

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

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

I have 2 interfaces IA and IB. 我有2个接口IA和IB。

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

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

    void SetIA(IA value);
}

Each interfaces references the other. 每个接口引用另一个。

I am trying to serialize ClassA as defined below. 我正在尝试按以下定义序列化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;
    }
}

I get an error when I try too serialize because the 2 properties are interfaces. 我尝试过序列化时出错,因为2个属性是接口。 I want to serialize the properties. 我想序列化属性。

How would I get around this? 我怎么能绕过这个?

I need to have references in each interface to the other. 我需要在每个接口中引用另一个接口。 And I need to be able to serialize the class back and forth. 我需要能够来回序列化这个类。

You have various bugs in your code, otherwise this would work just fine. 您的代码中有各种错误,否则这样可以正常工作。

  1. In the constructor for ClassA , your are setting an local variable IB, not the object's IB object. ClassA的构造函数中,您正在设置局部变量IB,而不是对象的IB对象。
  2. In ClassB , you are casting back to the object concrete class, instead of leaving it alone as the interface type. ClassB ,您将回退到对象具体类,而不是将其作为接口类型单独使用。

Here is what your code should look like: 以下是您的代码应如下所示:

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

Implement ISerializable on your objects to control the serialization. 在对象上实现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);
  }
}

Assuming you don't want to serialize the interface property, place the following attribute 假设您不想序列化接口属性,请放置以下属性

[NonSerialized]

on the interface property. 在接口属性上。

In return for your question: two other questions. 作为回答您的问题:另外两个问题。 What do you Serialize? 你怎么序列化? Is the database reference-aware? 数据库是否可识别引用?

You don't serialize interfaces; 你没有序列化接口; you serialize objects. 你序列化对象。 The object you serialize is either an implementation of IA or IB. 您序列化的对象是IA或IB的实现。

It's up to the serialized object to decide whether one of it's properties should be serialized or not. 由序列化对象决定是否应该序列化其中一个属性。 If the property does need serializing, it should implement the Serializable interface. 如果属性确实需要序列化,则应实现Serializable接口。

You can only serialize a so called 'island' formed by a circular reference A <-> B if the database can identify the serialized objects: it should first 'allocate' space for A, start serializing A's properties. 如果数据库可以识别序列化对象,则只能序列化由循环引用A < - > B形成的所谓“岛”:它应首先为A分配空间,开始序列化A的属性。 When it arrives at B, it will find one of it's properties referring to A. The serialization should then include a reference to the serialized version of A. 当它到达B时,它将找到其中一个引用A的属性。序列化应该包括对A的序列化版本的引用。

It's much like two acquaintances moving houses at the same time: first they will exchange their future adresses, only then they will physically move. 这就像两个熟人在同一时间搬家一样:首先他们会交换他们未来的地址,然后他们才会实际搬家。

Interface properties are not serializable. 接口属性不可序列化。 However, fields that reference those properties (in the subclass) are. 但是,引用这些属性的字段(在子类中)是。

You'll need to do something like this: 你需要做这样的事情:

[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.

相关问题 序列化具有接口的对象 - Serialize an object that has an interface 如何使用接口类型化数组属性序列化对象? - How to serialize object with interface typed array property? 如何使用Dictionary序列化对象 <string,object> 属性? - How can I serialize an object with a Dictionary<string,object> property? 如何在没有某些属性名称的情况下序列化对象 - How can I serialize object without some property names 如何序列化接口默认属性? - How to serialize interface default property? 我如何序列化具有ObservableCollection类型的属性的WPF自定义控件? - How can i serialize a WPF custom control which has a property of type ObservableCollection? 我如何序列化一个对象,其中该对象具有从操作创建的委托? - How can I serialize an object where the object has a Delegate created from an Action? 如果我从通用 function 序列化 object ,其中 object 的属性不在其接口上,那么序列化的 object 上会有什么属性? - If I serialize an object from a generic function where the object has properties not on its interface, what will be on the serialized object? 如何覆盖属性的 JSON 序列化,以将值序列化为字符串而不是 object? - How can I override the JSON serialization for a property, to serialize the value as a string instead of an object? 如何序列化 object 但给定属性仍序列化为字节数组? - How can I serialize an object but have a given property remain serialized to a byte array?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM