前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >运行时序列化 5

运行时序列化 5

作者头像
小蜜蜂
发布2019-07-23 15:29:57
4470
发布2019-07-23 15:29:57
举报
文章被收录于专栏:明丰随笔

反序列化对象时重写程序集/类型

序列化对象时,格式化器输出类型及其定义的程序集全名。反序列化对象时,格式化器根据这个信息确定要为对象构造并初始化什么类型。但是有时候有必要将对象反序列成和序列化时不同的类型。

1. 一个类型的实现从一个程序集移到了另一个程序集。

2. 服务器对象序列化传输给客户端,客户端反序列不同类型的对象。

3. 开发人员创建了类型的新版本,想把已序列化的对象反序列化到类型的新版本。

根据之前的文章是可以做到的,但是比较繁琐。

本文会提供另一种机制,可以非常简单地将一个对象流反序列化成不同类型的对象。

利用SerializationBinder类,可以方便满足我们的需求。

1. 首先有一个名为Ver1类。

2. 然后还有一个名为Ver2类。

3. 自定义一个Ver1ToVer2SerializationBinder类,它继承SerializationBinder类。

4. 重写SerializationBinder类的BindToType方法,把Ver1的对象流反序列化成Ver2对象。

5. 构造自定义的SerializationBinder类的实例并设置格式化器的Binder属性。

6. 格式化器在调用Deserialize方法的时候,它会检查Binder属性,格式化器会调用里面的BindToType方法,向它传递程序集名称以及格式化器想要反序列化的类型。然后BindToType根据这个类型判断出来实际应该构建什么类型,并返回这个类型。

代码简单实现:

代码语言:javascript
复制
[Serializable]
class Ver1
{
  public int MyProperty { get; set; }
}

[Serializable]
class Ver2
{
  public int MyProperty { get; set; }
}

class Ver1ToVer2SerializationBinder: SerializationBinder
{
  public override Type BindToType(string assemblyName, string typeName)
  {
    AssemblyName assemblyVer1 = Assembly.GetExecutingAssembly().GetName();
    assemblyVer1.Version = new Version(1, 0, 0, 0);

    if (assemblyName == assemblyVer1.ToString() && typeName == "SerializeDemo.SerializationBinderDemo.Ver1")
    {
      return typeof(Ver2);
    }
    return Type.GetType(string.Format("{0}, {1}", typeName, assemblyName));
  }
}

using (MemoryStream stream = new MemoryStream())
{
  IFormatter formatter = new BinaryFormatter();
  formatter.Binder = new Ver1ToVer2SerializationBinder();
  Ver1 ver1 = new Ver1() { MyProperty = 3 };
  formatter.Serialize(stream, ver1);
  stream.Position = 0;
  var ver2 = (Ver2)formatter.Deserialize(stream);
}

SerializationBinder类里面还有一个BindToName方法,

代码语言:javascript
复制
public virtual void BindToName(Type serializedType, out string assemblyName, out string typeName)
{
  assemblyName = null;
  typeName = null;
}

它是一个虚方法,可以重写。

通过这个方法可以在序列化对象时更改程序集和类型的信息。

格式化器调用这个方法,获取应该序列化成为什么类型,我们可以通过重写这个方法,给out string assemblyName和out string typeName返回真正想要序列化到的类型。默认两个参数都是返回null,就不执行任何程序集和类型的更改。

本文回顾:

反序列化对象时重写程序集/类型?

重写SerializationBinder类的BindToType方法。

序列化对象时重写程序集/类型?

重写SerializationBinder类的BindToName方法。

-纸上得来终觉浅,绝知此事要躬行-

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 明丰随笔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档