[Serializable]在C#中的作用-NET 中的对象序列化
来源:互联网 发布:cms系统源码下载 编辑:程序博客网 时间:2024/04/29 04:53
简介 在面向对象的环境中实现序列化机制时,必须在易用性和灵活性之间进行一些权衡。只要您对此过程有足够的控制能力,就可以使该过程在很大程度上自动进行。例如,简单的二进制序列化不能满足需要,或者,由于特定原因需要确定类中那些字段需要序列化。以下各部分将探讨 .NET 框架提供的可靠的序列化机制,并着重介绍使您可以根据需要自定义序列化过程的一些重要功能。 持久存储 公共语言运行时 (CLR) 管理对象在内存中的分布,.NET 框架则通过使用反射提供自动的序列化机制。对象序列化后,类的名称、程序集以及类实例的所有数据成员均被写入存储媒体中。对象通常用成员变量来存储对其他实例的引用。类序列化后,序列化引擎将跟踪所有已序列化的引用对象,以确保同一对象不被序列化多次。.NET 框架所提供的序列化体系结构可以自动正确处理对象图表和循环引用。对对象图表的唯一要求是,由正在进行序列化的对象所引用的所有对象都必须标记为 Serializable(请参阅基本序列化)。否则,当序列化程序试图序列化未标记的对象时将会出现异常。 当反序列化已序列化的类时,将重新创建该类,并自动还原所有数据成员的值。 按值封送 如果对象是从 MarshalByRefObject 派生得到,则从一个应用程序域传递至另一个应用程序域的是对象引用,而不是对象本身。也可以将从 MarshalByRefObject 派生得到的对象标记为 Serializable。远程使用此对象时,负责进行序列化并已预先配置为 SurrogateSelector 的格式化程序将控制序列化过程,并用一个代理替换所有从 MarshalByRefObject 派生得到的对象。如果没有预先配置为 SurrogateSelector,序列化体系结构将遵从下面的标准序列化规则(请参阅序列化过程的步骤)。 基本序列化 [Serializable] MyObject obj = new MyObject(); 将对象还原到它以前的状态也非常容易。首先,创建格式化程序和流以进行读取,然后让格式化程序对对象进行反序列化。以下代码片段说明了如何进行此操作。 IFormatter formatter = new BinaryFormatter(); // 下面是证明 如果要求具有可移植性,请使用 SoapFormatter。所要做的更改只是将以上代码中的格式化程序换成 SoapFormatter,而 Serialize 和 Deserialize 调用不变。对于上面使用的示例,该格式化程序将生成以下结果。 <SOAP-ENV:Envelope <SOAP-ENV:Body> public class MyStuff : MyObject 选择性序列化 [Serializable] [Serializable] public MyObject() protected MyObject(SerializationInfo info, StreamingContext context) public virtual void GetObjectData(SerializationInfo info, 需要强调的是,将 ISerializable 添加至某个类时,需要同时实现 GetObjectData 以及特殊的构造函数。如果缺少 GetObjectData,编译器将发出警告。但是,由于无法强制实现构造函数,所以,缺少构造函数时不会发出警告。如果在没有构造函数的情况下尝试反序列化某个类,将会出现异常。在消除潜在安全性和版本控制问题等方面,当前设计优于 SetObjectData 方法。例如,如果将 SetObjectData 方法定义为某个接口的一部分,则此方法必须是公共方法,这使得用户不得不编写代码来防止多次调用 SetObjectData 方法。可以想象,如果某个对象正在执行某些操作,而某个恶意应用程序却调用此对象的 SetObjectData 方法,将会引起一些潜在的麻烦。 在反序列化过程中,使用出于此目的而提供的构造函数将 SerializationInfo 传递给类。对象反序列化时,对构造函数的任何可见性约束都将被忽略,因此,可以将类标记为 public、protected、internal 或 private。一个不错的办法是,在类未封装的情况下,将构造函数标记为 protect。如果类已封装,则应标记为 private。要还原对象的状态,只需使用序列化时采用的名称,从 SerializationInfo 中检索变量的值。如果基类实现了 ISerializable,则应调用基类的构造函数,以使基础对象可以还原其变量。 如果从实现了 ISerializable 的类派生出一个新的类,则只要新的类中含有任何需要序列化的变量,就必须同时实现构造函数以及 GetObjectData 方法。以下代码片段显示了如何使用上文所示的 MyObject 类来完成此操作。 [Serializable] public ObjectTwo() : base() protected ObjectTwo(SerializationInfo si, StreamingContext context) : public override void GetObjectData(SerializationInfo si, 对象被彻底重新构建,但是在反系列化过程中调用方法可能会带来不良的副作用,因为被调用的方法可能引用了在调用时尚未反序列化的对象引用。如果正在进行反序列化的类实现了 IDeserializationCallback,则反序列化整个对象图表后,将自动调用 OnSerialization 方法。此时,引用的所有子对象均已完全还原。有些类不使用上述事件侦听器,很难对它们进行反序列化,散列表便是一个典型的例子。在反序列化过程中检索关键字/值对非常容易,但是,由于无法保证从散列表派生出的类已反序列化,所以把这些对象添加回散列表时会出现一些问题。因此,建议目前不要在散列表上调用方法。 序列化过程的步骤 检查格式化程序是否有代理选取器。如果有,检查代理选取器是否处理指定类型的对象。如果选取器处理此对象类型,将在代理选取器上调用 ISerializable.GetObjectData。 如果对象的状态需要在不同版本间发生改变,类的作者可以有两种选择: 实现 ISerializable。这使您可以精确地控制序列化和反序列化过程,在反序列化过程中正确地添加和解释未来状态。 所有的类都永远也不会跨越应用程序域。如果某个类不要求序列化但需要跨越应用程序域,请从 MarshalByRefObject 派生此类。 |
- [Serializable]在C#中的作用-NET 中的对象序列化
- Serializable在C#中的作用.NET 中的对象序列化
- Serializable在C#中的作用.NET 中的对象序列化
- [Serializable]在C#中的作用-NET 中的对象序列化
- Serializable在C#中的作用.NET 中的对象序列化
- [Serializable]在C#中的作用,.NET 中的对象序列化
- [Serializable]在C#中的作用-NET 中的对象序列化
- [Serializable]在C#中的作用-NET 中的对象序列化
- Serializable在C#中的作用.NET 中的对象序列化
- Serializable在C#中的作用.NET 中的对象序列化
- Serializable在C#中的作用.NET 中的对象序列化
- [Serializable]在C#中的作用-NET 中的对象序列化
- [Serializable]在C#中的作用-NET 中的对象序列化
- [Serializable]在C#中的作用-NET 中的对象序列化
- [Serializable]在C#中的作用-NET 中的对象序列化
- Serializable在C#中的作用.NET 中的对象序列化
- [Serializable]在C#中的作用-NET 中的对象序列化
- [Serializable]在C#中的作用-NET 中的对象序列化
- C#格式化数值结果表
- ABAP门派现状报告
- 从某种意义上说实践是最好的方式
- MY-SQL数据库用户密码修改
- 微软语音技术 Windows 语音编程初步
- [Serializable]在C#中的作用-NET 中的对象序列化
- c#2.0中新增的两个压缩类(downmoon原创)c#
- GTK+图形化应用程序开发学习笔记(一)—概述
- 一个集成微软语音识别技术与语音朗读的类,基于Microsoft SpeechAPI5.1的开发
- VC++中的ON_COMMAND_RANGE宏
- C#中接口与抽象类的区别
- 使用VC++6.0+microsoft speech API 实现语音识别示例
- 什么是看门狗
- VC++如何编写一个语音识别的类for Micosoft speech Api5.1