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

kev*_*vin 307 .net c# serialization

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

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

Cha*_*thJ 362

它是什么?

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

用于序列化

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

应用于SerializableAttribute类型以指示可以序列化此类型的实例.应用SerializableAttribute即使类还实现了ISerializable控制序列化过程的界面.

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

有关详细信息,请参阅MSDN.

编辑1

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

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

  • 有什么理由不将某些东西标记为可序列化的? (24认同)
  • 很好的解释,将它添加到 MSDN 中的属性会很好 =) (2认同)

Bra*_*ith 41

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

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

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


BLa*_*ack 31

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

这有点令人困惑,除非你真正关注细节,何时使用它以及它的实际目的是什么.

它与XML或JSON序列化无关.

与SerializableAttribute一起使用的是ISerializable Interface和SerializationInfo类.这些也只与BinaryFormatter或SoapFormatter一起使用.

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

  • "它与XML或JSON序列化无关" - 谢谢!最后解释为什么我可以愉快地将任何类序列化为XML,无论是否具有此属性 (12认同)
  • 请注意,Microsoft 正在积极努力从 .NET 中删除 BinaryFormatter,并且 [SerializableAttribute 将在 .NET 8 中被标记为过时](https://github.com/dotnet/designs/blob/main/accepted/2020/better-废弃/binaryformatter-obsoletion.md#new-obsoletions-in-net-8)。 (6认同)
  • 你有这个来源吗? (2认同)

Mah*_*man 27

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

序列化的工作原理

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

在此输入图像描述

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

msdn中的详细信息


Aks*_*hay 18

以下是序列化工作原理的简短示例.我也在学习同样的东西,我发现两个链接很有用. 序列化是什么以及如何在.NET中完成.

解释序列化的示例程序

如果你不理解上面的程序,这里给出一个简单的解释程序.


She*_*ngh 12

序列化

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

序列化的使用

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

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

[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
        }

    }
Run Code Online (Sandbox Code Playgroud)

这是调用代码

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

    }
Run Code Online (Sandbox Code Playgroud)