什么是[Serializable]以及何时使用它?

时间:2011-05-04 02:29:40

标签: c# .net serialization

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

  • 这是什么?
  • 我什么时候应该使用它?
  • 我会得到什么样的好处?

6 个答案:

答案 0 :(得分:347)

这是什么?

在.Net框架应用程序中创建对象时,您无需考虑如何将数据存储在内存中。因为.Net Framework会为您解决这个问题。但是,如果要将对象的内容存储到文件,将对象发送到另一个进程或通过网络传输,则必须考虑如何表示对象,因为您需要转换为其他格式。此转换称为SERIALIZATION。

用于序列化

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

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

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

有关详细信息,请参阅MSDN

修改1

  

任何不将某些内容标记为可序列化的原因

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

答案 1 :(得分:38)

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

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

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

答案 2 :(得分:25)

  

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

序列化工作原理

此图显示了序列化的整个过程。

enter image description here

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

Details in msdn.

答案 3 :(得分:21)

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

除非您真的很注意细节,何时使用它以及它的实际用途是什么,否则这会造成一些混乱。

它与XML或JSON序列化无关。

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

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

答案 4 :(得分:18)

以下是序列化工作原理的简短示例。我也在学习同样的东西,我发现两个链接很有用。 What Serialization is and how it can be done in .NET

A sample program explaining serialization

如果您不理解上述程序,则会给出一个简单的解释程序here

答案 5 :(得分:11)

<强>序列化

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

序列化的使用

  1. 将对象的状态保存到文件,数据库等中并使用后者。
  2. 在同一台计算机上将对象从一个进程发送到另一个进程(App Domain),并通过网络将其发送到另一台计算机上运行的进程。
  3. 在处理主对象时创建原始对象的克隆作为备份。
  4. 可以轻松地将一组对象复制到系统的剪贴板,然后粘贴到相同或另一个应用程序中
  5. 以下是在对象序列化期间使用的一些有用的自定义属性

    [可序列化] - &gt;当我们标记对象的可序列化时使用它 [NonSerialized] - &gt;当我们不想序列化对象的字段时使用它。 [OnSerializing] - &gt;当我们想要在序列化对象时执行某些操作时使用它 [OnSerialized] - &gt;在将对象序列化为流后,我们想要执行某些操作时使用它。

    以下是序列化的示例

    [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();
            }
    
        }