首页 / C# / 如何在C#反序列化期间进行引用修复?
如何在C#反序列化期间进行引用修复?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了如何在C#反序列化期间进行引用修复?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3639字,纯文字阅读大概需要6分钟。
内容图文
如何使用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, Name = "Fluttershy", 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)序列化.
This帖子是另一个信息来源
编辑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, StreamingContext ontext) {
info.AddValue("Id", Id);
info.AddValue("Name", Name);
info.AddValue("BFF.Id", BFF.Id);
}
…
内容总结
以上是互联网集市为您收集整理的如何在C#反序列化期间进行引用修复?全部内容,希望文章能够帮你解决如何在C#反序列化期间进行引用修复?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。