Serializable和ISerializable的区别,还有FormatterServices的用途

来源:互联网 发布:steam动态壁纸软件mac 编辑:程序博客网 时间:2024/06/05 13:28

记得上周,我开始看mscorlib 1.1的时候,发现所有的Exception都是derived from System.Exception的,这个相信很多人都知道,但是很多次我都看到,每个派生自System.Exception的异常类,都有一个protected的构造方法,两个参数,一个是SerializationInfo,一个是StreamingContext,而且每个Exception类都实现了ISerializable接口,并在类上标住了[Serializable]的属性,从字面上可以看出是可序列化的,而且后者,相信大家也都用到过,但是前者,我相信用的人就不那么多了,关键问题不在谁用过哪个,没用过哪个,而且这两个到底有什么区别,这是我的疑问,经过Google Serializable vs ISerializable,我发现了如下参考文献中两篇非常有价值的文章,在此我用我理解的意思描述一下,他们的基本概念:

 

  1. SerializableISerializable都是用于标示可序列化的结构,类,枚举等对象的
  2. Serializable属性原理是基于反射的,标示了这个属性的对象,在序列化的时候,.NET会反射这个对象的所有public, private成员,将之序列化,反之则是反序列化
  3. ISerializable接口,实现了它的对象,会要求实现一个方法,一个protected构造,前一个方法用于序列化,后一个构造用于反序列化,传递的参数就是SerializationInfoStreamingContext

 

以上是对他们的基本概念的描述,但还没说到区别,区别如下:

 

  1. Serializable属性是很方便的,系统会帮你反射自动序列化所有public,private fields但是性能有影响,而且无法定制,只有一个定制控制就是[Serializable][NonSerialized],可控制哪些可序列化,哪些不可序列化。存在的问题就是:当序列化的对象,字段域发生了更改,添加,删除修改的时候,这个对象之前旧的序列化对象,就不再支持反序列化了,这是其第二大弱点,别着急,这两个缺点,就是为什么用ISerializable接口的问题
  1. ISerializable接口的出现,用于实现自定义的序列化操作,通过protected .ctor(SerializationInfo,StreamingContext)void GetObjectData(SerializationInfo,StreamingContext)两个方法,就可以实现自定义的反序列化和序列化,也就是,由你完全控制这些过程,即使对象发生修改,旧的序列化对象也可以过度到新的对象
  1. 要想实现序列化,无论是否实现ISerializable接口,都要在对象上标识属性[Serialiable],才可以支持对象序列化
  1. 另外在继承的情况下,还存在一些注意点,例如当父类仅标示了[Serializable],但没有实现ISerializable接口,在其派生类,由于想定制序列化,实现了ISerializable接口,但是父类没有实现,就出现了,派生类如何将继承的快速序列化,这里除了手动的一一书写外,还可以一步到位,两条语句就可以讲父类的所有成员序列化或反序列化,那就是使用System.Runtime.Serialization.FormatterService类,这个类主要有三个静态方法,一个是获得某一个类型的所有可序列化成员 MemberInfo[] GetSerializableMembers(Type type);另一个是获得某个实例对象的所有序列化后的数据 object[] GetObjectData(object obj, MemberInfo[] members),此方法可用于序列化;最后一个方法用于反序列化 object PopulateObjectMember(object obj, MemberInfo[] members, object[] data),将序列化后的数据,反序列化给当前实例对象,返回反序列化后的对象。也就是通过这个FormatterService类,我们可以对任何类型的实例实现手动的序列化/反序列化
原创粉丝点击