可以使用 OnDeserializedAttribute 代替 IDeserializationCallback 接口吗?

2024-04-12

正如 MSDN 所说here http://msdn.microsoft.com/en-us/library/system.runtime.serialization.ondeserializedattribute.aspx, 它可以。 但我花了 2 个小时挖掘 mscorlib 代码,因为在某些情况下,BinaryFormatter 在反序列化构造函数之前调用了标有 OnDeserialized 的方法。也就是说,订单是

OnDeserializing(StreamingContext context)
OnDeserialized(StreamingContext context)
.ctor(SerializationInfo info, StreamingContext context)

当我期待它是

OnDeserializing(StreamingContext context)
.ctor(SerializationInfo info, StreamingContext context)
OnDeserialized(StreamingContext context)

最后一点。当我实现 IDeserializationCallback 接口时,它的方法 OnDeserialization 在构造函数之后被调用,正如我想要和预期的那样。

我尝试在一些简单的类结构上重现这一点,但一切正常。 在我们的项目中,被序列化的对象图非常复杂,所以我不知道在哪里挖掘。使用反射器检查 mscorlib 代码并没有多大帮助 - 反序列化代码对我来说太复杂了,无法找出问题出在哪里。

那么,有人知道什么可能导致这样的问题吗?我们假设 OnDeserialized 在其他几个地方的构造函数之前被调用,所以我现在很害怕它不是很可靠......

Thanks!


最后,我自己的问题有了答案,如果有人感兴趣的话。 考虑本文末尾的示例。有两个类,它们的实例包含彼此的引用。在这种情况下,两个实例的反序列化构造函数不可能与构造对象一起传递。因此,序列化器首先调用一个构造函数,向其传递第二类型的未构造实例,然后调用该对象的构造函数,向其传递第一类型的构造实例。通过这种方式,它可以帮助我们恢复对象连接,所以它确实是它能做到的最好的!

Next, OnDeserializing and OnDeserialized在这种情况下的回调可能会像我在问题中指出的那样被调用,而OnDeserialization的方法IDeserializationCallback总是在 COMPLETE 对象图被反序列化之后调用,正如其规范中所述。

记住以上所有内容,我发现它是最好的使用IDeserializationCallback进行我需要的任何反序列化后处理的接口。在这种情况下,我确信所有对象都会调用构造函数,并且我可以以“安全”的方式进行必要的修改。

      [Serializable]
      class One :ISerializable, IDeserializationCallback
      {
           public Two m_two;
           public One() {}
           public One(SerializationInfo info, StreamingContext context)
           {
                var two = (Two)info.GetValue("m_two", typeof(Two));
                m_two = two;
           }
           public void GetObjectData(SerializationInfo info, StreamingContext context)
           {
                info.AddValue("m_two", m_two);
           }
           private bool m_onDeserializing;
           private bool m_onDeserialized;
           private bool m_callback;
           public void OnDeserialization(object sender)
           {
                m_callback = true;
           }
           [OnDeserializing]
           void OnDeserializing(StreamingContext context)
           {
                m_onDeserializing = true;
           }

           [OnDeserialized]
           void OnDeserialized(StreamingContext context)
           {
                m_onDeserialized = true;
           }
      }

      [Serializable]
      private class Two : ISerializable, IDeserializationCallback
      {
           public Two(){}
           public One m_one;
           public Two(SerializationInfo info, StreamingContext context)
           {
                var one = (One)info.GetValue("m_one", typeof(One));
                m_one = one;
           }
           public void GetObjectData(SerializationInfo info, StreamingContext context)
           {
                info.AddValue("m_one", m_one);
           }
           private bool m_onDeserializing;
           private bool m_onDeserialized;
           private bool m_callback;
           public void OnDeserialization(object sender)
           {
                m_callback = true;
           }
           [OnDeserializing]
           void OnDeserializing(StreamingContext context)
           {
                m_onDeserializing = true;
           }
           [OnDeserialized]
           void OnDeserialized(StreamingContext context)
           {
                m_onDeserialized = true;
           }
      }

      [STAThread]
      static void Main()
      {
           var one = new One();
           one.m_two = new Two();
           one.m_two.m_one = one;

           BinaryFormatter formatter = new BinaryFormatter();
           MemoryStream mss =new MemoryStream();
           formatter.Serialize(mss, one);
           mss.Position = 0;
           var deserialize = formatter.Deserialize(mss);
      }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

可以使用 OnDeserializedAttribute 代替 IDeserializationCallback 接口吗? 的相关文章

随机推荐

  • ajax请求后如何更改URL?

    我有一个菜单 其中包含一些更新 div 的链接content并执行该函数onSuccess加载后 li Ajax ActionLink Home Index home li li Ajax ActionLink Download Index
  • 通过编辑 AOSP 将 Android 导航栏放在侧面

    我想通过编辑 AOSP 将导航栏 具有后退 主页和菜单等系统软键 而不是导航抽屉 放在 右侧 侧 如下所示 Status bar always N Layout with background drawable a v Title Acti
  • Java - 替换 JFrame 中的组件

    我正在努力使用 java GUI 提前感谢您的帮助 我有一个 JFrame 其中有几个组件 按钮 J 按钮 触发动作侦听器 comp这是我试图替换的一个组件JScrollPane其中有一个组件 组件的类型无关紧要 可以是文本字段 表格或任何
  • android - TextView 中自动滚动的问题

    我有一个Activity它用作音乐播放器 当它开始时 一个MediaPlayer对象被初始化并启动 在布局中 我有TextViews显示艺术家和标题 这些值 从服务器检索 可能很长 所以我添加了 android ellipsize marq
  • ruby 中的网络掩码到 CIDR

    我一直在使用 ip address gem 它似乎无法从以下形式的网络掩码进行转换 255 255 255 0 进入 CIDR 表格 24 有谁知道如何快速将前者转换为后者 这是快速而肮脏的方法 require ipaddr puts IP
  • 使用 ramdajs 重命名对象的属性

    我需要使用以下命令将可能包含连字符的单词重写为驼峰命名法的对象的所有属性ramdajs 示例 属性名称animation timing function应该成为animationTimingFunction每个键依此类推 您能否举个例子 这
  • 为什么缩放填充会给出比 UIImageVIew 尺寸更大的图像? (使用快速)

    我正在尝试显示地名列表 包括它的照片PFQueryTableViewController 它包含在 ParseUI SDK 中解析网 http parse com 我已经成功地展示了图像 不幸的是 当我将 UIImageView 模式更改为
  • 需要帮助在 javascript 中的表之间切换

    我试图使用两个按钮来使用 javascript 在两个表之间切换 但是每当我测试时 两个表都会出现 而不是只出现一个 var table1 document getElementById table1 var table2 document
  • 最小可行的网站图标代码

    我很困惑什么是让网站图标在大多数手机和浏览器上工作的最简单方法 1 一些网站 https mathiasbynens be notes touch icons建议使用以下内容就足够了 这适用于 iOS 8 并且应该适用于 Android B
  • UI线程块

    我创建了一个简单的 WPF 应用程序 并向默认窗口添加了一个按钮 当我单击按钮时 会调用一个模拟的长工作方法 使用 Thread Sleep 15000 进行模拟 我试图使按钮异步执行 但是尽管遵循在线示例 按钮和整个窗口都会在我锁定时立即
  • “循环”引用是否会被视为 WeakMap 的“可达性”?

    function f const w new WeakMap const o w set o v o return w const weakMap f 对于给定的代码 唯一的weakMap项目是否被视为可达 那么 它会被垃圾收集吗 PS 这
  • 如何禁用 Google Fit 并撤销应用程序本身的权限

    我已经设置了连接到 Google Fit 的应用程序 读取和写入一些有关用户身体的数据 当用户在应用程序设置中禁用 Google Fit 时 我尝试通过调用以下命令来撤销我的应用程序权限 public void disableGoogleF
  • 当数据在缓存中时 Apollo Client client.readQuery 返回 null

    这一定是用户错误 但我有一个简单的应用程序currentUser查询在 JWT 中查找 id 查找它并返回相应的用户 我可以查看 devtools 并看到它在缓存中 ref User 19 export const CURRENT USER
  • 要在 Google App Engine 上托管静态 (HTML) 网站,app.yaml 文件中应包含哪些内容?

    我可以用它来上传 HTML 页面吗 app yaml内容 application visualvidya version 1 runtime python api version 1 handlers url gif png jpg ico
  • 我应该在 HTML 中使用 % 或 'px'

    无论是 HTML XHTML 还是 HTML5 您都会发现到处都是令人讨厌的百分比 然而 我看到很多网站都不敢靠近它们 然而大学总是鼓励我使用它们 那么我应该使用哪个 哪一个会带来更好的网站设计 为什么 我知道要避免使用高度 尽管如果我想使
  • 使用锚点提交表单安全吗?

    我在某处读到 使用锚标记提交表单不太安全 所以这就是我的问题 使用锚标记而不是安全吗
  • Curl 同时下载和上传同一文件

    不确定是否可能 但我一直在尝试使用curl 从 HTTP 位置下载文件并将其输出到 FTP 服务器上 如果这实际上可能的话 我真的很希望得到一些帮助 curl http example com down curl T ftp mysite
  • 捕获 Flask API 中引发的自定义异常。引发的所有异常最终都会出现 500 错误 [重复]

    这个问题在这里已经有答案了 我希望能够在 API 中引发验证和其他异常 并在包装 视图中捕获它们 该视图将以 JSON 形式返回错误消息 我想我可以使用这样的东西 例外 class APIException Exception def in
  • AWS 批处理始终为每个作业启动新的 ec2 实例

    我已经设置了一个批处理环境 托管计算环境 作业队列 职位定义 实际工作 docker 容器 执行大量视频编码 因此占用了大部分 CPU 该过程本身需要几分钟 初始化所有编码器大约需要 5 分钟 理想情况下 我希望每个实例执行一项作业 这样编
  • 可以使用 OnDeserializedAttribute 代替 IDeserializationCallback 接口吗?

    正如 MSDN 所说here http msdn microsoft com en us library system runtime serialization ondeserializedattribute aspx 它可以 但我花了