[序列化]

序列化是将对象状态转换为可保持或传输的形式的过程。序列化的补集是反序列化,后者将流转换为对象。这两个过程一起保证数据易于存储和传输。

.NET Framework 提供了两个序列化技术:

  • 二进制序列化保持类型保真,这对于多次调用应用程序时保持对象状态非常有用。例如,通过将对象序列化到剪贴板,可在不同的应用程序之间共享对象。您可以将对象序列化到流、磁盘、内存和网络等。远程处理使用序列化,“按值”在计算机或应用程序域之间传递对象。

  • XML 序列化只序列化公共属性和字段,并且不保持类型保真。当您希望提供或使用数据而不限制使用该数据的应用程序时,这一点非常有用。由于 XML 是开放式的标准,因此它对于通过 Web 共享数据来说是一个理想选择。SOAP 同样是开放式的标准,这使它也成为一个理想选择。

标准序列化,自定义序列化

ms-help://MS.MSDNQTR.v90.chs/ws_fxserialization/html/d899d43c-335a-433e-a589-cd187192984f.htm

使类可序列化的最简单方法是按以下方式使用 Serializable 属性对其进行标记。

[Serializable]
public class MyObject {
  public int n1 = 0;
  public int n2 = 0;
  public String str = null;
}

//将此类的实例序列化为文件

MyObject obj = new MyObject();
obj.n1 = 1;
obj.n2 = 24;
obj.str = "Some String";
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Create, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, obj);//关键
stream.Close();

类的所有成员变量都将被序列化,即使将变量标记为私有也是如此。在这一方面,二进制序列化与 XMLSerializer 类不同,后者只序列化公共字段。

反序列化

IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Open, FileAccess.Read, FileShare.Read);
MyObject obj = (MyObject) formatter.Deserialize(stream);
stream.Close();

// Here's the proof.
Console.WriteLine("n1: {0}", obj.n1);
Console.WriteLine("n2: {0}", obj.n2);
Console.WriteLine("str: {0}", obj.str);

要特别注意的是,无法继承 Serializable 属性。如果从 MyObject 派生新类,新类也必须标记为以上属性,否则将无法序列化。例如,尝试序列化以下类的实例时,将收到 SerializationException,通知您 MyStuff 类型未标记为可序列化。

public class MyStuff : MyObject 
{
  public int n3;
}

类数据成员包含敏感信息。在此情况下,建议将类标记为可序列化,但建议用 NonSerializedAttribute 属性标记包含敏感信息的各数据成员。另一个方法是实现 ISerializable 接口并只序列化所需的字段。

防止对成员变量进行序列化,方法是使用 NonSerialized 属性标记它们

[Serializable]
public class MyObject 
{
  public int n1;
  [NonSerialized] public int n2;
  public String str;
}

实现 ISerializable 接口 :描述如何使用 ISerializable 接口自定义对类的序列化。

序列化过程中的步骤

在格式化程序上调用 Serialize 方法时,将按照以下规则顺序进行对象序列化:

  • 进行检查以确定格式化程序是否具有代理项选择器。如果有,则检查代理项选择器是否处理给定类型的对象。如果选择器处理该对象类型,则在代理项选择器上调用 ISerializable.GetObjectData

  • 如果没有代理项选择器,或者代理项选择器不处理该对象类型,则进行检查以确定是否用 Serializable 属性标记了该对象。如果未标记该对象,则会引发 SerializationException。

  • 如果已相应地标记了对象,则检查该对象是否实现 ISerializable 接口。如果对象已实现该接口,则针对该对象调用 GetObjectData。

  • 如果对象未实现 ISerializable,则使用默认序列化策略,从而序列化所有未标记为 NonSerialized 的字段。

XML 序列化  ms-help://MS.MSDNQTR.v90.chs/ws_fxserialization/html/832ac524-21bc-419a-a27b-ca8bfc45840f.htm

XML 序列化只将对象的公共字段和属性值序列化为 XML 流。XML 序列化不包括类型信息。例如,如果 Library 命名空间中存在 Book 对象,则不能保证将它反序列化为同一类型的对象。

Note注意:

XML 序列化不能转换方法、索引器、私有字段或只读属性(只读集合除外)。要序列化对象的所有公共和私有字段和属性,请使用 BinaryFormatter 而不要使用 XML 序列化。

ms-help://MS.MSDNQTR.v90.chs/ws_fxserialization/html/4d1111c0-9447-4231-a997-96a2b74b3453.htm

原文地址:https://www.cnblogs.com/StudyLife/p/2586682.html