为什么使用序列化

本文关键字:序列化 为什么 | 更新日期: 2023-09-27 18:36:47

我见过几个具有可序列化属性的示例,如下所示:

[Serializable()]
            public class sampleClass
            {
                public int Property1{ get; set; }
                public string Proerty2{ get; set; }
                public sampleClass() { }
                public sampleClass(int pr1, int pr2)
                {
                    pr1 = pr1;
                    Name = pr2.ToString();
                }
            }

我从来没有很好地理解它是如何工作的,但从 msdn:

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

但问题是,在我的代码示例中,我认为它没有任何用处。只是一个用于从数据库中检索数据的对象,没什么特别的。关于何时使用和何时不使用序列化的其他用途是什么。例如,我是否应该始终使用序列化,因为它更安全?这样慢一点是不是要慢一点?

更新:感谢所有不错的答案

为什么使用序列化

每当你想要将数据的表示形式移入或移出进程边界时,序列化都很有用。

将对象保存到磁盘是一个简单的示例,您将在许多教程中看到。

更常见的是,序列化用于将数据传入和传出 Web 服务,或者将数据保存到数据库或从数据库保存数据。

有几个答案涵盖了为什么您可能想要使用序列化的原因。您似乎还想知道为什么特定类具有属性[Serializable]并且您想知道为什么要这样做。

使用 ASP.NET 默认会话状态存储是InProc它允许您将任何对象存储为引用并将其保留在堆上。这是存储会话状态的最佳性能方法,但是,仅当您使用单个工作线程时,或者如果工作线程发生更改(不太可能),则可以自动重建所有会话状态。对于其他状态存储模式(StateServerSQL Server),所有会话状态对象都必须是可序列化的,因为 ASP.NET 引擎将首先使用二进制序列化来序列化这些对象,然后再将它们发送到存储介质。

在您的情况下,您可能正在使用 InProc .但是,仍然将会话状态中使用的所有类标记为Serializable并以这种方式对其进行测试的一个原因是,将来可能需要更改此设置(例如,使用 Web 场)。如果您没有考虑到这一点来设计会话状态类,那么将来进行迁移将非常困难。

此外,仅仅因为您可以删除 Serializable 属性并且程序在一个环境中"工作"并不意味着它将在另一个环境中工作。例如,它可能在Visual Studio测试Web服务器(始终InProc使用会话状态模式)实例下工作正常,甚至在开发IIS实例中也是如此,但是,也许将生产IIS实例设置为使用不同的存储模式。

这些环境/配置差异不一定仅限于 ASP.NET 应用程序。还有其他应用程序引擎可以这样做,甚至是独立的应用程序可以这样做(构建这种可配置的环境并不难)。

最后,您可能正在使用可能被不同应用程序使用的库。有些可能需要以可序列化的方式存储状态,而另一些则不需要。

由于这些因素,至少在构建库时,考虑使用 [Serializable] 标记简单值类或状态管理类通常是一个非常好的主意。请记住,这增加了测试这些类的工作量,并且对可以序列化的内容有限制(即,包含套接字引用或打开文件引用的类可能不适合序列化,因为开放的外部资源无法序列化),所以不要过度使用它。

你问使用[Serializable]是否会变慢。不,不会。此属性对性能没有直接影响。但是,如果将应用程序环境更改为序列化对象,则是的,性能将受到影响。序列化和反序列化的行为比仅将对象存储在堆上要慢。[请注意,可以编写一些例程来查找 Serializable 属性,然后选择序列化,但这种情况很少见;通常它就像 ASP.NET,由管理员或用户决定是否要更改存储介质。

您提供的 MSDN 报价说明了序列化何时有用:用于传输或存储数据。写入文件是序列化,并且需要序列化而不是通过网络发送对象。

如果您只是在单个应用程序中填充对象,也许是从数据库中填充,那么确实:序列化根本不是一个问题。对类进行映像以进行序列化对安全性或性能没有影响:如果不需要它,请不要担心它。

另请注意,[Serializable]主要与BinaryFormatter有关,但实际上还有比这更多的序列化程序。例如:您可能希望通过 JSON 或 XML 公开对象 - 两者都需要序列化,但都不需要[Serializable]

简单示例:假设您有一个自定义形状来存储应用程序设置。

namespace My.Namespace
{
    [Serializable]
    public class Settings
    {
        public string Setting1 { get; set; }
        public string Setting2 { get; set; }
    }
}

然后,您可以将一个文件作为 xml 文件:

<?xml version="1.0" encoding="utf-8" ?>
<Settings>
  <Setting1>Foo</Setting1>
  <Setting2>Bar</Setting2>
</Settings>

使用 XmlSerializer,您可以简单地序列化和反序列化您的设置。

如果您希望将

形状填充到视图状态 ASP.NET 则形状也必须是可序列化

这些是非常基本的例子,但证明了它的有用性

关于何时使用和何时不使用序列化的其他用途是什么。

让我举一个实际的例子。在我的一个应用程序中,我得到了XML个模式(XSD文件),用于请求和响应XML文件。我需要解析请求XML文件,处理并将信息保存回几个表中。稍后我需要相应地准备响应XML文件并将其发送回我们的客户。

我使用 Xsd2Code 基于架构生成C#类。因此,解析请求XML文件只是将其反序列化为生成的请求类对象。然后,我可以按照对象在请求XML文件中的显示方式从对象访问属性。生成响应时XML文件只是从我在代码中填充的生成的响应类对象序列化。这样,我就可以处理 C# 对象而不是XML文件。我希望这是有道理的。

例如,我是否应该始终使用序列化,因为它更安全

我认为这与安全性没有任何关系。