6

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

[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 字符串通过防火墙传递,或者维护安全性或用户特定跨应用程序的信息。

但问题是,在我的代码示例中,我认为它没有用。只是一个用于从数据库中检索数据的对象,没什么特别的。关于何时使用和何时不使用序列化还有哪些其他用途。例如,我应该总是使用序列化,因为它更安全吗?这种方式会变慢吗?

更新:感谢所有好的答案

4

5 回答 5

6

当您想将数据表示移入或移出流程边界时,序列化非常有用。

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

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

于 2012-06-08T19:46:09.677 回答
5

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

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

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

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

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

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

由于这些因素,至少在构建库时,考虑使用[Serializable]. 请记住,这会增加测试这些类的工作量,并且对可以序列化的内容有限制(即,包含套接字引用或打开文件引用的类可能不是序列化的良好候选者,因为无法序列化打开的外部资源)所以不要过度使用它。

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

于 2012-06-09T01:21:48.907 回答
3

您提供的 MSDN 引用解释了序列化何时有用:用于传输或存储数据。写入文件是序列化,并且需要序列化才能通过网络发送对象。

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

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

于 2012-06-08T19:50:54.480 回答
0

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

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 ViewState 中,那么您的形状也必须是可序列化的

这些是非常基本的示例,但证明了它的用处

于 2012-06-08T19:54:15.043 回答
0

关于何时使用和何时不使用序列化还有哪些其他用途。

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

我曾经根据模式Xsd2Code生成C#类。所以解析请求XML文件只是简单的将其反序列化为生成的请求类对象。然后我可以访问对象的属性,就像它出现在请求XML文件中一样。虽然生成响应XML文件只是从我在代码中填充的生成响应类对象进行序列化。这样我就可以使用 C# 对象而不是XML文件。我希望这是有道理的。

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

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

于 2012-06-09T17:19:42.187 回答