什么是[Serializable],什么时候我应该使用它?

我发现一些类使用[Serializable]属性。

  • 是什么?
  • 什么时候使用?
  • 我能得到哪些福利?
296450 次浏览

是什么?

在. net框架应用程序中创建对象时,不需要考虑数据是如何存储在内存中的。因为. net框架会帮你处理这些。但是,如果您想将对象的内容存储到文件中,将对象发送到另一个进程或通过网络传输它,则必须考虑对象是如何表示的,因为您将需要转换为不同的格式。这种转换称为序列化。

序列化的用途

序列化允许开发人员保存对象的状态并根据需要重新创建它,从而提供对象的存储和数据交换。通过序列化,开发人员可以执行一些操作,比如通过Web服务将对象发送到远程应用程序,将对象从一个域传递到另一个域,将对象作为XML字符串通过防火墙传递,或者跨应用程序维护安全性或特定于用户的信息。

SerializableAttribute应用于类型以指示该类型的实例可以序列化。即使类还实现了ISerializable接口来控制序列化过程,也要应用SerializableAttribute

默认情况下,由SerializableAttribute标记的类型中的所有公共和私有字段都是序列化的,除非该类型实现了ISerializable接口来覆盖序列化过程。默认的序列化过程会排除标记为NonSerializedAttribute的字段。如果可序列化类型的字段包含指针、句柄或特定于特定环境的其他数据结构,并且不能在不同的环境中有意义地重构,那么您可能希望对该字段应用NonSerializedAttribute

更多细节参见MSDN

编辑1

任何不将某些东西标记为可序列化的理由

在传输或保存数据时,只需要发送或保存需要的数据。这样就会减少传输延迟和存储问题。因此,在序列化时可以选择排除不必要的数据块。

[Serializable]属性的一些实际用途:

  • 使用二进制序列化保存对象状态;你可以很容易地将应用程序中的整个对象实例“保存”到一个文件或网络流中,然后通过反序列化重新创建它们——查看System.Runtime.Serialization.Formatters.Binary中的BinaryFormatter
  • 编写对象实例可以使用Clipboard.SetData()存储在剪贴板上的类——不可序列化的类不能放在剪贴板上。
  • 编写与.NET Remoting兼容的类;通常,在应用程序域之间传递的任何类实例(除了那些从MarshalByRefObject扩展而来的类)必须是可序列化的。

这些是我遇到的最常见的用例。

下面是序列化如何工作的简短示例。我也在学习同样的东西,我发现两个链接很有用。 什么是序列化,以及如何在。net中实现序列化 . < / p >

一个解释序列化的示例程序

如果你不理解上面的程序,一个非常简单的程序有解释在这里

序列化是将对象转换为字节流以存储对象或将其传输到内存、数据库或文件的过程。

序列化的工作原理

下图显示了序列化的整个过程:

enter image description here

对象被序列化为携带数据的流。流还可能包含关于对象类型的信息,例如它的版本、区域性和程序集名称。从该流中,对象可以存储在数据库、文件或内存中。

详细信息在微软文档中。

序列化

序列化是将一个对象或一组对象图转换为流的过程,在二进制序列化的情况下是一个字节数组

序列化的用途

  1. 保存一个对象的状态到一个文件,数据库等,并在以后使用它。
  2. 将一个对象从一个进程发送到同一机器上的另一个进程(应用程序域),也可以通过有线发送到运行在另一台机器上的进程。
  3. 在处理主对象时创建原始对象的克隆作为备份。
  4. 一组对象可以很容易地复制到系统的剪贴板,然后粘贴到相同或另一个应用程序

下面是在对象序列化期间使用的一些有用的自定义属性

(序列化) ->当标记对象的可序列化时使用 (NonSerialized) ->当我们不想序列化一个对象的字段时使用。 (OnSerializing) ->当我们想在序列化对象时执行某些操作时使用 [OnSerialized] ->当我们将一个对象序列化到流后想要执行一些操作时使用。

下面是序列化的示例

[Serializable]
internal class DemoForSerializable
{
internal string Fname = string.Empty;
internal string Lname = string.Empty;


internal Stream SerializeToMS(DemoForSerializable demo)
{
DemoForSerializable objSer = new DemoForSerializable();
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, objSer);
return ms;
}


[OnSerializing]
private void OnSerializing(StreamingContext context) {
Fname = "sheo";
Lname = "Dayal";
}
[OnSerialized]
private void OnSerialized(StreamingContext context)
{
// Do some work after serialized object
}


}

下面是调用代码

class Program
{
string fname = string.Empty;
string Lname = string.Empty;


static void Main(string[] args)
{
DemoForSerializable demo = new DemoForSerializable();


Stream ms = demo.SerializeToMS(demo);
ms.Position = 0;


DemoForSerializable demo1 = new BinaryFormatter().Deserialize(ms) as DemoForSerializable;


Console.WriteLine(demo1.Fname);
Console.WriteLine(demo1.Lname);
Console.ReadLine();
}


}

由于最初的问题是关于SerializableAttribute的,因此应该注意,该属性仅适用于使用BinaryFormatter或SoapFormatter时。

这有点令人困惑,除非你真的注意到细节,比如什么时候使用它,它的实际用途是什么。

它与XML或JSON序列化无关。

与SerializableAttribute一起使用的是serialalizable接口和SerializationInfo类。这些也只与BinaryFormatter或SoapFormatter一起使用。

除非您打算使用Binary或Soap序列化您的类,否则不要费心将您的类标记为[Serializable]。XML和JSON序列化器甚至不知道它的存在。