[英]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. 您的代码中有各种错误,否则这样可以正常工作。
ClassA
, your are setting an local variable IB, not the object's IB object. 在ClassA
的构造函数中,您正在设置局部变量IB,而不是对象的IB对象。 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.