为什么类在.Net中默认不可序列化?

时间:2010-12-10 12:42:00

标签: .net serialization types

开发人员必须通过明确使用SerializableAttribute来“选择”使类可序列化。如果类默认可序列化会出现什么问题?

5 个答案:

答案 0 :(得分:26)

我认为默认情况下类不可序列化,因为无法保证使用Reflection将对象状态转储到流中甚至是有意义的。如果对象保持与a的开放连接怎么办?数据库还是通讯端口?每当通过反序列化前一个对象的实例来构造新对象时,最终会得到一个无用的对象。

另外,您必须考虑每当类可序列化时,运行时都会坚持其所有成员变量也是可序列化的,除非明确标记它们。将可序列化作为开发人员的 in 功能更容易,而不是强迫他们选择 out 某些成员。

最后,您的类中可能包含某些包含私人或敏感信息的字段。必须明确地将类标记为可序列化,这样可以确保您不会意外地将某些内容(无论是数据还是实现)的详细信息暴露给您并不想公开的世界。

答案 1 :(得分:4)

可序列化类意味着它们具有某种状态,可以写入外部位置并再次读取。对于很多没有任何意义的类 - 一个Thread有什么样的状态,你可以成功地序列化?

这有点哲学但按照惯例,类的默认类型不可序列化,除非您明确定义“此类可以序列化”。

答案 2 :(得分:3)

IMO [Serializable]令人困惑,很大程度上是因为大多数序列化确实需要 。我的意思是:有更多的代码使用XmlSerializer(包括asmx),DataContractSerializer(包括WCF),JavaScriptSerializer(包括MVC的JsonResult),或者像protobuf-net等等。[Serializable]主要是BinaryFormatter,它是(来自我的)明确下降。并且有很多充分的理由。

至于原因:其他答案解决了这个问题,但并不总是使意义来序列化某些东西。当然实体对象可以充当DTO,但很难以健壮的方式检测到它。

所以IMO对我是否[Serializable]的影响可以忽略不计,但我同意默认值:你应该知道你打算序列化某些东西。在某些情况下,这种序列化意味着额外的工作(特别是因为一些序列化程序不运行ctor / init代码,所以你需要知道正确准备字段。)

答案 3 :(得分:3)

Liskov替换原则意味着如果一个类是可序列化的,那么所有派生类也应该是可序列化的。如果类默认是可序列化的,那么在不违反Liskov替换原则的情况下导出非可序列化类非常困难。

答案 4 :(得分:0)

将所有类标记为可序列化可能更好,除非:

  • 他们永远不会跨越应用程序域。如果不需要序列化并且类需要跨越应用程序域,则从MarshalByRefObject派生类。
  • 该类存储仅适用于该类的当前实例的特殊指针。例如,如果类包含非托管内存或文件句柄,请确保将这些字段标记为NonSerialized或根本不对该类进行序列化。
  • 某些数据成员包含敏感信息。在这种情况下,建议实现ISerializable并仅序列化必需的字段。

价:Object Serialization in the .NET Framework