【问题标题】:Has the design of marker interfaces like Java's Serializable or Cloneable evolved in C#?标记接口(如 Java 的 Serializable 或 Cloneable)的设计是否在 C# 中演变?
【发布时间】:2011-09-13 03:51:47
【问题描述】:

Java 在他的标准库中提供了java.io.Serializablejava.lang.Cloneable(并在语言和 JVM 中提供了对它的特殊支持)用于反序列化/序列化/克隆的任务。

C# 是否选择了不同的路径来提供此功能,使用它的实现和代码与 Java 有何不同,为什么这样做?

举个例子,为什么C#同时使用属性(注解)和接口进行序列化?

【问题讨论】:

  • C# 提供了许多序列化选项——例如ISerializable(标记),或[DataContract][Serializable](属性)等。所有情况都要求序列化程序知道如何“读取”那种类/对象,但从根本上讲,它并没有太大的不同。

标签: c# java serialization language-design cloneable


【解决方案1】:

如果您想了解有关序列化的信息:check this

【讨论】:

    【解决方案2】:

    不确定您所说的“进化”是什么意思,如果有的话,我认为趋势是朝向属性而不是标记界面。我不知道 Java 最近是不是也这样。

    例如,CLR 中的序列化在其最基本的属性形式中得到证明,尽管您可以实现一些非标记接口,以便在需要时更好地控制流程。

    【讨论】:

      【解决方案3】:

      .NET 不将ISerializable 用作标记接口。它不仅充当标记,还允许您通过实现 GetObjectData 和采用合适参数的构造函数来精确控制 .NET 如何序列化类。

      当类可以序列化,但不想定义自己的序列化行为时使用该属性。

      所以:当你想定义自己的序列化行为时,使用ISerializable;或者当您想将其留给序列化格式化程序时使用 [Serializable] 属性。

      我可以称之为进化吗?我不知道。 .NET 只是为您提供不同程度的灵活性。

      【讨论】:

      • 好的,谢谢指正。我查看了 MSDN 文档并没有看到 GetObjectData 是在 ISerializable 上定义的(它在选择 .NET 4.0 时出现,但在选择 .NET 3.5/2.0 时不会出现)。我认为它的行为仍然与 Java 中的 Serializable 相当,它没有“正式”定义一个方法,而是会寻找一些具有特定名称的方法并带有一点 VM 魔法? Afaik 这样做是为了不需要公开与 GetObjectData 等效的 JVM。
      • 该特定页面上的 MSDN 文档是错误的。 GetObjectData 方法一直存在。由于它位于接口上,它必须对 C# 公开,因为这是合同的重点。从 .NET 框架 1.0 开始,这就是 ISerializable 的目的:实现该方法来控制序列化。这是另一个正确记录的页面:msdn.microsoft.com/en-us/library/…
      【解决方案4】:

      标记接口可能是用 Java 实现的最糟糕的决定之一。我的意思是看看 Cloneable 到底有多没用,因为没有人在接口中定义公共 clone() 方法。

      .NET 不朝那个方向发展(至少我不知道该方向的任何接口)与其说是一种进化,不如说是对整个概念的放弃。似乎越来越多的另一个方向似乎是注释,我假设您可以将其视为“标记”,但在更基本的层面上(例如,我很确定今天是否实现了 Java 瞬态将是一个注释和不是限定词)

      【讨论】:

      • 是的,在 Scala 中,transient 最终是一个注解(就像@throws@native@volatile、...参见scala-lang.org/node/106)。 @serializablescala.Serializable 抛弃了(虽然扩展 java.io.Serializable...
      • @Soc 很有趣。任何关于他们为什么决定使用 Serializable 接口而不是注释的链接(我的意思是创建 java 字节码需要更多的工作,但是因为他们已经在为字段/方法做类似的事情,这似乎不是大问题)-也许我应该问一个关于那个的问题..关于何时在类级别使用接口/注释的有趣概念。
      • 当然,继续创建一个问题。这将是一个很好的问题。 Afaik 这与 java 兼容性有关...编辑:找到了! scala-programming-language.1934581.n4.nabble.com/…
      • 啊兼容性仍然。在我看来,我假设 scala 创建了 java 代码并用基本的 java 类型/接口替换了注释,然后再将其提供给编译器,在这种情况下,这不会是一个问题 - 似乎没有以这种方式实现 ;) 关于接口与注解 this 线程有一些观点,尽管我认为它的实现有点过于具体,而且没有我想象的那么开放
      • 是的,他们基本上就是这么做的。但似乎在查看注释之前处理了类型,假设注释不能更改类型层次结构。但这正是这里的情况。修复它需要更深入地混合注释处理和类型处理代码,这被拒绝了,因为它会使编译器代码相当复杂。
      【解决方案5】:

      我不认为 C# 已经进化了。相反,他们解决了这两件事:

      • Java中的序列化不是很干净:反序列化涉及对象“创建”而不调用构造函数,整个过程可以包括运行时调用私有方法等。 如果您有兴趣,请查看the specs

      • Cloneable 完全坏掉了。它不应该是标记接口,而是指定clone() 方法。因为你有Cloneables 你不能clone()

      基本上,Java 中有很多东西,主要是从 1.2 之前的版本开始,非常糟糕/混乱/不干净/随便什么。

      【讨论】:

        猜你喜欢
        • 2011-09-13
        • 1970-01-01
        • 2012-04-09
        • 2010-12-31
        • 2011-01-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多