积极答复者
请教一个很让人郁闷的对象序列化问题

问题
-
测试代码如下
对TypeC序列化后再反序列化,结果发现里面collection全为null,这是为什么呢?
有什么办法可以解决吗?[Serializable] struct TypeA { public double A1; public double A2; public double A3; public TypeA(double a) { A1 = a; A2 = a; A3 = a; } } [Serializable] class TypeB : ISerializable { private readonly List<TypeA> collection = new List<TypeA>(); public TypeB() { collection.Add(new TypeA(1)); collection.Add(new TypeA(2)); collection.Add(new TypeA(3)); collection.Add(new TypeA(4)); collection.Add(new TypeA(5)); } #region ISerializable Members protected TypeB(SerializationInfo info, StreamingContext context) { collection.AddRange(info.GetValue("B", typeof(List<TypeA>)) as List<TypeA>); } public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("B", collection, typeof(List<TypeA>)); } #endregion } [Serializable] class TypeC : ISerializable { private readonly List<TypeB> collection = new List<TypeB>(); public TypeC() { collection.Add(new TypeB()); collection.Add(new TypeB()); collection.Add(new TypeB()); } protected TypeC(SerializationInfo info, StreamingContext context) { collection.AddRange(info.GetValue("C", typeof(TypeB[])) as TypeB[]); } public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("C", collection.ToArray()); } } class Program { static void Main(string[] args) { using(MemoryStream stream = new MemoryStream()) { TypeC c = new TypeC(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, c); stream.Seek(0, SeekOrigin.Begin);
// 反序列化后,结果与预期不一致 TypeC c2 = formatter.Deserialize(stream) as TypeC; } using(MemoryStream stream = new MemoryStream()) { TypeB b = new TypeB(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, b); stream.Seek(0, SeekOrigin.Begin); TypeB b2 = formatter.Deserialize(stream) as TypeB; } using(MemoryStream stream = new MemoryStream()) { TypeB[] b = new TypeB[2]; b[0] = new TypeB(); b[1] = new TypeB(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, b); stream.Seek(0, SeekOrigin.Begin); TypeB[] b2 = formatter.Deserialize(stream) as TypeB[]; } } }- 已移动 Sheng Jiang 蒋晟 2009年12月16日 20:00 System.Xml (发件人:Visual C#)
- 已更改类型 Andrew_Zhu 2009年12月23日 8:47
- 已更改类型 Andrew_Zhu 2009年12月23日 8:58
2009年12月16日 13:44
答案
-
你好!
我认为这行代码有问题:
collection.AddRange(info.GetValue("C" , typeof (TypeB[])) as TypeB[]);
对象将被彻底重新构造,并且在反序列化期间调用方法可能会产生不良的副作用,因为被调用的方法可能引用在进行此调用时尚未被反序列化的对象引用。
周雪峰- 已标记为答案 Andrew_Zhu 2009年12月23日 9:37
2009年12月16日 16:00
全部回复
-
你好!
我认为这行代码有问题:
collection.AddRange(info.GetValue("C" , typeof (TypeB[])) as TypeB[]);
对象将被彻底重新构造,并且在反序列化期间调用方法可能会产生不良的副作用,因为被调用的方法可能引用在进行此调用时尚未被反序列化的对象引用。
周雪峰- 已标记为答案 Andrew_Zhu 2009年12月23日 9:37
2009年12月16日 16:00 -
你好!
我认为这行代码有问题:
collection.AddRange(info.GetValue("C" , typeof (TypeB[])) as TypeB[]);
对象将被彻底重新构造,并且在反序列化期间调用方法可能会产生不良的副作用,因为被调用的方法可能引用在进行此调用时尚未被反序列化的对象引用。
周雪峰
对象为readonly,不会再次重建
这行代码即使改成TypeB[] bs = info.GetValue("C" , typeof (TypeB[])) as TypeB[]; 也会出同样的问题,bs[0] bs[1]... 为null2009年12月16日 16:34 -
这个帖子怎么会移到 XML 与 Web Services 讨论区 这个地方了呢???2009年12月17日 1:21
-
把 ISerializable 接口的方法全部去掉,就可以了。
This posting is provided "AS IS" with no warranties, and confers no rights. Microsoft Online Community Support- 已标记为答案 Andrew_Zhu 2009年12月23日 9:37
- 取消答案标记 Daniel Sun 2009年12月24日 1:20
2009年12月23日 9:33