ChatGPT解决这个技术问题 Extra ChatGPT

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

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

它是什么?

我应该什么时候使用它?

我将获得哪些好处?


C
Community

它是什么?

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

用于序列化

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

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

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

有关详细信息,请参阅 MSDN

编辑 1

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

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


很好的解释,很高兴将其添加到 MSDN 中的属性 =)
@jayasurya_j 太糟糕了,接受的答案并没有过多地谈论 private parts
很好的解释
B
BLaminack

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

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

它与 XML 或 JSON 序列化无关。

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

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


“它与 XML 或 JSON 序列化无关” - 谢谢!最后解释一下为什么我可以愉快地将任何类序列化为带有或不带有此属性的 XML
你有这个的来源吗?
“XML 和 JSON 序列化程序甚至都不知道它的存在”。我不知道那件事。当我通过 WCF 对一个类进行 JSON 格式设置时,如果该类是 Serializable,则属性名称带有前面的下划线,而当属性被删除时则没有。所以一些干扰是可能的。
@Jens 如果我理解正确,JSON.net 一点也不关心它,但 asp.net 稍微改变了这种行为。我相信您可以使用 JsonObject / JsonProperty 属性来规避这一点。
此处对类似问题的支持性答案:stackoverflow.com/a/12461510/388664
B
Bradley Smith

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

使用二进制序列化保存对象状态;您可以非常轻松地将应用程序中的整个对象实例“保存”到文件或网络流中,然后通过反序列化重新创建它们 - 查看 System.Runtime.Serialization.Formatters.Binary 中的 BinaryFormatter 类

使用 Clipboard.SetData() 编写对象实例可以存储在剪贴板上的类 - 不可序列化的类不能放在剪贴板上。

编写与 .NET Remoting 兼容的类;通常,您在应用程序域之间传递的任何类实例(从 MarshalByRefObject 扩展的类实例除外)都必须是可序列化的。

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


P
Pang

序列化是将对象转换为字节流以存储对象或将其传输到内存、数据库或文件的过程。序列化的工作原理 下图显示了序列化的整个过程: 对象被序列化为携带数据的流。该流还可能包含有关对象类型的信息,例如其版本、文化和程序集名称。从该流中,对象可以存储在数据库、文件或内存中。

Microsoft Docs 中的详细信息。


S
Stacked

这是序列化如何工作的简短示例。我也在学习相同的内容,发现两个链接很有用。 What Serialization is and how it can be done in .NET

A sample program explaining serialization

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


S
Sheo Dayal Singh

序列化

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

序列化的用途

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

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

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

    }