C# ISerializable接口的意义是什么?

C# ISerializable接口的意义是什么?,c#,serializable,iserializable,C#,Serializable,Iserializable,似乎我可以序列化没有该接口的类,所以我不清楚它的用途。使用ISerializable可以在对象中编写自定义方法,以便在执行二进制序列化时接管序列化,以与BinaryFormatter使用的默认方法不同的方式序列化对象 换句话说,如果默认方法序列化对象的方式不同于您希望将其序列化为的方式,那么您可以实现ISerializable以实现完全控制。请注意,在ISerializable的帮助下,还应该实现一个自定义构造函数 XmlSerialization当然只使用属性,ISerializable与XM

似乎我可以序列化没有该接口的类,所以我不清楚它的用途。

使用
ISerializable
可以在对象中编写自定义方法,以便在执行二进制序列化时接管序列化,以与BinaryFormatter使用的默认方法不同的方式序列化对象

换句话说,如果默认方法序列化对象的方式不同于您希望将其序列化为的方式,那么您可以实现ISerializable以实现完全控制。请注意,在ISerializable的帮助下,还应该实现一个自定义构造函数

XmlSerialization当然只使用属性,ISerializable与XML序列化无关


感谢Marc和Pop的评论,我的第一个答案有点仓促。

类可以通过以下两种方式之一在.NET中序列化:

  • SerializableAttribute
    标记类,并用
    非序列化属性修饰所有不希望序列化的字段。(正如Marc Gravell指出的,
    BinaryFormatter
    ,通常用于格式化
    ISerializable
    对象的类,会自动序列化所有字段,除非它们被特别标记为其他字段。)
  • 实现用于完全自定义序列化的
    ISerializable
    接口
  • 前者使用起来更简单,因为它只涉及用属性标记声明,但其功能有限。后者允许更大的灵活性,但需要更多的努力来实现。您应该使用哪一个完全取决于上下文

    关于后者(
    ISerializable
    )和it使用,我引用了界面的:

    任何可能被序列化的类 必须用 序列化属性。如果一个班级 需要控制其序列化 过程中,它可以实现 ISerializable接口。格式化程序 调用位于的GetObjectData 序列化时间并填充 提供的SerializationInfo包含所有 所需的数据表示 对象格式化程序创建一个 类型为的SerializationInfo 对象。需要 为自己发送代理可以使用 FullTypeName和AssemblyName 要更改的SerializationInfo上的方法 传输的信息

    在类继承的情况下,它 可以序列化 派生自 实现ISerializable。在这个 在这种情况下,派生类应该调用 的基类实现 其内部的GetObjectData GetObjectData的实现。 否则,数据将从数据库中删除 类将不会序列化


    为了使对象“可传输”,必须将其序列化。例如,如果要使用.NET远程处理或Web服务传输对象数据,则必须提供序列化对象数据的方法,将对象实例缩减为表示对象高保真表示的可传输格式

    然后,您还可以获取序列化表示,将其传输到另一个上下文(如不同的机器),并重新生成原始对象

    实现
    ISerializable
    接口时,类必须提供接口中包含的GetObjectData方法,以及专用于接受两个参数的专用构造函数:SerializationInfo实例和StreamingContext实例


    如果您的类不需要对其对象状态进行细粒度控制,那么您可以使用
    [Serializable]
    属性。需要对序列化过程进行更多控制的类可以实现ISerializable接口。

    ISerializable
    用于提供自定义二进制序列化,通常用于
    BinaryFormatter
    (可能用于远程处理)。如果没有它,它将使用以下字段:

    • 低效的;如果有一些字段在运行时仅用于提高效率,但可以为序列化而删除(例如,字典在序列化时可能看起来不同)
    • 低效的;即使对于需要的字段,它也需要包含大量额外的元数据
    • 无效;如果存在无法序列化的字段(例如事件委托,尽管它们可以标记为
      [非序列化]
    • 易碎;您的序列化现在绑定到字段名,但字段是一个实现细节;另见
    通过实现ISerializable,您可以提供自己的二进制序列化机制。请注意,与此等价的xml是
    IXmlSerializable
    ,由
    XmlSerializer
    等使用

    出于数据传输的目的,应该避免使用
    BinaryFormatter
    ——像xml(通过
    XmlSerializer
    DataContractSerializer
    )或json这样的东西,就像协议缓冲区这样的跨平台格式一样


    为了完整起见,protobuf net确实包含了
    ISerializable
    的钩子(允许您使用可移植的二进制格式,而无需编写大量代码),但无论如何,
    BinaryFormatter
    并不是您的首选。

    ISerializable是一个接口,而不是一个属性。您的问题是关于接口ISerializable还是SerializableAttribute类?@Martin,在问题本身中,他只提到属性。所以我猜问题不在于界面。如果有人可以编辑问题标题?我和Martin一样对这个问题感到困惑,但我认为这是关于接口的,因为他特别提到ISerializable@mek:如果你实际上是指属性,请让我知道/编辑这个问题。问题的编辑不好,是关于属性的。。。不是界面。他用了attribu这个词