c#

位置:IT落伍者 >> c# >> 浏览文章

c#实体类序列化方法


发布日期:2019年10月01日
 
c#实体类序列化方法

提到为了传递数据需要把作为载体的实体类序列化好好的找了一些序列化方面的介绍感觉下面的这个介绍比较容易介绍!

什么是序列化

序列化是将对象状态转换为可保持或传输的格式的过程在序列化过程中对象的公共字段和私有字段以及类的名称(包括包含该类的程序集)都被转换为字节流然后写入数据流与序列化相对的是反序列化它将流转换为对象这两个过程结合起来可以轻松地存储和传输数据

为什么使用序列化

a 一个原因是将对象的状态保持在存储媒体中以便可以在以后重新创建精确的副本

我们经常需要将对象的字段值保存到磁盘中并在以后检索此数据尽管不使用序列化也能完成这项工作但这种方法通常很繁琐而且容易出错并且在需要跟蹤对象的层次结构时会变得越来越复杂可以想象一下编写包含大量对象的大型业务应用程序的情形程序员不得不为每一个对象编写代码以便将字段和属性保存至磁盘以及从磁盘还原这些字段和属性序列化提供了轻松实现这个目标的快捷方法

b另一个原因是通过值将对象从一个应用程序域发送到另一个应用程序域中

例如序列化可用于在 ASPNET 中保存会话状态并将对象复制到 Windows 窗体的剪贴板中远程处理还可以使用序列化通过值将对象从一个应用程序域传递到另一个应用程序域中

公共语言运行时 (CLR) 管理对象在内存中的分布NET 框架则通过使用反射提供自动的序列化机制对象序列化后类的名称程序集以及类实例的所有数据成员均被写入存储媒体中对象通常用成员变量来存储对其他实例的引用类序列化后序列化引擎将跟蹤所有已序列化的引用对象以确保同一对象不被序列化多次NET 框架所提供的序列化体系结构可以自动正确处理对象图表和循环引用对对象图表的唯一要求是由正在进行序列化的对象所引用的所有对象都必须标记为 Serializable(请参阅基本序列化)否则当序列化程序试图序列化未标记的对象时将会出现异常

当反序列化已序列化的类时将重新创建该类并自动还原所有数据成员的值

如何实现对象的序列化及反序列化

要实现对象的序列化首先要保证该对象可以序列化而且序列化只是将对象的属性进行有效的保存对于对象的一些方法则无法实现序列化的

实现一个类可序列化的最简便的方法就是增加Serializable属性标记类

[Serializable()]

public class MEABlock

{

private int m_ID;

public string Caption;

public MEABlock()

{

///构造函数

}

}

即可实现该类的可序列化注意序列化的类必须为Public否则不能够被序列化

要将该类的实例序列化为到文件中?NET FrameWork提供了两种方法

a XML序列化

使用 XmLSerializer 类可将下列项序列化

公共类的公共读/写属性和字段

实现 ICollection 或 IEnumerable 的类(注意只有集合会被序列化而公共属性却不会

XmlElement 对象

XmlNode 对象

DataSet 对象

要实现上述类的实例的序列化可参照如下例子

MEABlock myBlock = new MEABlock();

// Insert code to set properties and fields of the object

XmlSerializer mySerializer = new XmlSerializer(typeof(MEABlock));

// To write to a file create a StreamWriter object

StreamWriter myWriter = new StreamWriter(myFileNamexml);

mySerializerSerialize(myWriter MEABlock);

需要注意的是XML序列化只会将public的字段保存对于私有字段不予于保存

生成的XML文件格式如下

<MEABlock>

<Caption>Test</Caption>

</MEABlock>

对于对象的反序列化则如下

MEABlock myBlock;

// Constructs an instance of the XmlSerializer with the type

// of object that is being deserialized

XmlSerializer mySerializer = new XmlSerializer(typeof(MEABlock));

// To read the file creates a FileStream

FileStream myFileStream = new FileStream(myFileNamexml FileModeOpen);

// Calls the Deserialize method and casts to the object type

myBlock = (MEABlock)mySerializerDeserialize(myFileStream)

b 二进制序列化

与XML序列化不同的是二进制序列化可以将类的实例中所有字段(包括私有和公有)都进行序列化操作这就更方便更准确的还原了对象的副本

要实现上述类的实例的序列化可参照如下例子

MEABlock myBlock = new MEABlock();

// Insert code to set properties and fields of the object

IFormatter formatter = new BinaryFormatter();

Stream stream = new FileStream(MyFilebinFileModeCreateFileAccessWrite FileShareNone);

formatterSerialize(stream myBlock);

streamClose();

对于对象的反序列化则如下

IFormatter formatter = new BinaryFormatter();

Stream stream = new FileStream(MyFilebin FileModeOpenFileAccessRead FileShareRead);

MEABlock myBlock = (MEABlock) formatterDeserialize(stream);

streamClose();

如何变相实现自定义可视化控件的序列化反序列化

对于WinForm中自定义控件由于继承于SystemWindowsForm类而Form类又是从MarshalByRefObject继承的窗体本身无法做到序列化窗体的实现基于Win下GUI资源不能脱离当前上下文存在

当然可以采用变通的方法实现控件的序列化这里采用的是记忆类模型

定义记忆类(其实就是一个可序列化的实体类)用于记录控件的有效属性需要序列化控件的时候只需要将该控件的实例Copy到记忆类演变成序列化保存该记忆类的操作

反序列化是一个逆过程将数据流反序列化成为该记忆类再根据该记忆类的属性生成控件实例而对于控件的一些事件方法则可以继续使用

wwf之所以强调要把类实例化就是因为工作流和应用程序是在不同的线程中二者之间需要用类作为传递数据的载体的话就需要把该类定义为public序列化为二进制传输

               

上一篇:.Net Framework提供的配置文件操作

下一篇:.Net WebBrowser 控件获取POST数据