如何使用C#序列化框架引用修复(后处理)?
我有一个对象图,其中的对象引用其他对象.它们都实现了ISerializable接口,并且它们都具有实例ID,因此在序列化状态下表示引用很容易.
krux是当调用反序列化构造函数时,该对象引用的所有对象可能都没有被反序列化,因此引用不能设置为有效对象.我找不到任何方法可以挂钩C#序列化框架中的后处理步骤来进行参考修复.有办法吗?
根据要求,这是一个人为的课程,我认为突出了问题.
[Serializable] public class Pony : ISerializable { public int Id { get; set; } public string Name { get; set; } public Pony BFF { get; set; } public Pony() {} private Pony(SerializationInfo info,StreamingContext context) { Id = info.GetInt32("id"); Name = info.GetString("name"); var bffId = info.GetInt32("BFFId"); BFF = null; // <===== Fixup! Find Pony instance with id == bffId } public void GetobjectData(SerializationInfo info,StreamingContext ontext) { info.AddValue("id",Id); info.AddValue("name",Name); info.AddValue("BFFId",BFF.Id); } }
这是(de)序列化代码:
var rd = new Pony { Id = 1,Name = "Rainbow Dash" }; var fs = new Pony { Id = 2,Name = "Fluttershy",BFF = rd }; rd.BFF = fs; var ponies = new List<Pony>{ rd,fs }; Stream stream = new MemoryStream(); var formatter = new BinaryFormatter(); formatter.Serialize(stream,ponies); stream.Seek(0,SeekOrigin.Begin); var deserializedPonies = (List<Pony>)formatter.Deserialize(stream);
这个问题没有解决我的问题:.net XML Serialization – Storing Reference instead of Object Copy
我想使用BinaryFormatter ISerializable框架进行序列化,而不是切换到XmlFormater.
解决方法
为此目的有一个属性.
在要反序列化的任何对象中实现以下方法:
[OnDeserialized] internal void OnDeserializedMethod(StreamingContext context) { }
System.Runtime.Serialization中还有一些属性可能会对您有所帮助.
编辑
[Serializable] public class Pony { public int Id { get; set; } public string Name { get; set; } public Pony BFF { get; set; } public Pony() { } [OnDeserialized] internal void OnDeserializedMethod(StreamingContext context) { Console.WriteLine(this.Id + " " + this.Name + " " + this.BFF?.Name); } }
测试方法:
var rd = new Pony { Id = 1,Name = "Rainbow Dash" }; var fs = new Pony { Id = 2,BFF = rd }; rd.BFF = fs; var ponies = new List<Pony> { rd,fs }; object returnValue; using (var memoryStream = new MemoryStream()) { var binaryFormatter = new BinaryFormatter(); binaryFormatter.Serialize(memoryStream,ponies); memoryStream.Position = 0; returnValue = binaryFormatter.Deserialize(memoryStream); } var xx = (List<Pony>)returnValue;
如您所见,我删除了ISerializable接口,私有构造函数和GetobjectData – Method.
我做到了,因为我不认为你真的需要它,因为你没有说,你已经实现了(De)序列化.
编辑2(Testmethod保持不变):
方法一(完全反序列化和序列化)
…
private Pony(SerializationInfo info,StreamingContext context) { foreach (SerializationEntry entry in info) { switch (entry.Name) { case "Id": this.Id = (int)entry.Value; break; case "Name": this.Name = (string)entry.Value; break; case "BFF": this.BFF = (Pony)entry.Value; break; } } } public void GetobjectData(SerializationInfo info,StreamingContext ontext) { info.AddValue("Id",Id); info.AddValue("Name",Name); info.AddValue("BFF",BFF); } }
…
方法2(递归对象 – 仅限Id):
…
private Pony(SerializationInfo info,StreamingContext context) { foreach (SerializationEntry entry in info) { switch (entry.Name) { case "Id": this.Id = (int)entry.Value; break; case "Name": this.Name = (string)entry.Value; break; case "BFF.Id": var bffId = (int)entry.Value; this.BFF = GetPonyById(bffId); // You have to implement this break; } } } public void GetobjectData(SerializationInfo info,Name); info.AddValue("BFF.Id",BFF.Id); }
…
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。