【发布时间】:2011-08-18 04:20:29
【问题描述】:
我发现有些类使用[Serializable] 属性。
- 这是什么?
- 什么时候应该使用它?
- 我将获得哪些福利?
【问题讨论】:
-
Here's我找到的一个实际用法说明。
标签: c# .net serialization
我发现有些类使用[Serializable] 属性。
【问题讨论】:
标签: c# .net serialization
当您在 .Net 框架应用程序中创建对象时,您无需考虑数据是如何存储在内存中的。因为 .Net 框架会为您处理这些问题。但是,如果要将对象的内容存储到文件中,将对象发送到另一个进程或通过网络传输,则必须考虑对象的表示方式,因为您需要转换为不同的格式.这种转换称为序列化。
序列化允许开发人员保存对象的状态并根据需要重新创建它,提供对象的存储以及数据交换。通过序列化,开发人员可以执行以下操作,例如通过 Web 服务将对象发送到远程应用程序、将对象从一个域传递到另一个域、将对象作为 XML 字符串通过防火墙传递,或者维护安全性或用户特定跨应用程序的信息。
将SerializableAttribute 应用于一个类型以指示该类型的实例可以被序列化。应用SerializableAttribute,即使该类也实现了ISerializable接口来控制序列化过程。
一个类型中所有被SerializableAttribute标记的公共和私有字段都默认被序列化,除非该类型实现了ISerializable接口来覆盖序列化过程。默认序列化过程不包括标有NonSerializedAttribute 的字段。如果可序列化类型的字段包含特定于特定环境的指针、句柄或其他一些数据结构,并且无法在不同的环境中有意义地重构,那么您可能希望将NonSerializedAttribute 应用于该字段。
详情请见MSDN。
编辑 1
任何不将某些东西标记为可序列化的理由
传输或保存数据时,您只需发送或保存所需的数据。所以会有更少的传输延迟和存储问题。因此,您可以在序列化时选择退出不必要的数据块。
【讨论】:
由于最初的问题是关于 SerializableAttribute,需要注意的是,该属性仅适用于使用 BinaryFormatter 或 SoapFormatter 时。
这有点令人困惑,除非你真的注意细节,什么时候使用它,它的实际用途是什么。
它与 XML 或 JSON 序列化无关。
与 SerializableAttribute 一起使用的是 ISerializable 接口和 SerializationInfo 类。这些也仅与 BinaryFormatter 或 SoapFormatter 一起使用。
除非您打算使用 Binary 或 Soap 序列化您的类,否则不要费心将您的类标记为 [Serializable]。 XML 和 JSON 序列化程序甚至都不知道它的存在。
【讨论】:
Serializable,则属性名称带有一个前面的下划线,而当属性被删除时则没有。所以有些干扰是可能的。
[Serializable] 属性的一些实际用途:
BinaryFormatter 类Clipboard.SetData() 存储在剪贴板上的类 - 不可序列化的类不能放在剪贴板上。MarshalByRefObject 扩展的类实例除外)都必须是可序列化的。这些是我遇到的最常见的使用案例。
【讨论】:
序列化是将对象转换为字节流以存储对象或将其传输到内存、数据库或文件的过程。
序列化的工作原理
此图展示了序列化的整体流程:
对象被序列化为携带数据的流。该流还可能包含有关对象类型的信息,例如其版本、文化和程序集名称。从该流中,对象可以存储在数据库、文件或内存中。
Microsoft Docs中的详细信息。
【讨论】:
这是序列化如何工作的简短示例。我也在学习相同的内容,发现两个链接很有用。 What Serialization is and how it can be done in .NET.
A sample program explaining serialization
如果你不理解上面的程序,一个非常简单的程序给出了解释here。
【讨论】:
序列化
序列化是将一个对象或一组对象图转换为流的过程,在二进制序列化的情况下是字节数组
序列化的使用
以下是在对象序列化期间使用的一些有用的自定义属性
[Serializable] -> 当我们标记一个对象的可序列化时使用 [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();
}
}
【讨论】: