加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

如何在C#反序列化期间进行引用修复?

发布时间:2020-12-15 22:32:30 所属栏目:百科 来源:网络整理
导读:如何使用C#序列化框架引用修复(后处理)? 我有一个对象图,其中的对象引用其他对象.它们都实现了ISerializable接口,并且它们都具有实例ID,因此在序列化状态下表示引用很容易. krux是当调用??反序列化构造函数时,该对象引用的所有对象可能都没有被反序列化,因
如何使用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)序列化.

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,Name);
      info.AddValue("BFF.Id",BFF.Id);
    }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读