在不实现任何自定义序列化/反序列化时,是否需要实现ISerializable接口

时间:2012-01-19 20:59:46

标签: c# serialization

我正在查看实现ISerializable接口的解决方案中的类。它具有接口所需的序列化GetObjectData方法。这里没有发生任何自定义序列化,它只是使用类的属性名称及其值填充SerializationInfo对象。

[Serializable]
public class PersonName :ISerializable
{
    [DataMember]
    public string NamePrefix { get; set; }
    [DataMember]
    public string GivenName { get; set; }
    [DataMember]
    public string SurName { get; set; }

    public PersonName(string givenName, string surName, string namePrefix)
    {
        GivenName = givenName;
        SurName = surName;
        NamePrefix = namePrefix;
    }

    public PersonName()
    {
    }

    #region ISerializable Members

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("NamePrefix",NamePrefix);
        info.AddValue("GivenName",GivenName);
        info.AddValue("SurName",SurName);
    }
}

从我到目前为止阅读的文档中,据我所知,这是因为类被标记为[Serializable]属性而发生的事情,并且您可以看到该类没有反序列化构造函数,这就是我开始看它的原因。从我所知,而不是需要将反序列化构造函数添加到类中,该类实际上不需要首先实现ISerializable接口。这是对的吗?

6 个答案:

答案 0 :(得分:14)

  

该类实际上不需要首先实现ISerializable接口。这是对的吗?

正确。实现ISerializable是指您需要执行除默认序列化行为之外的其他操作。 [Serializable]属性应该足够了。

答案 1 :(得分:8)

这是毫无意义的。

如果出于更好的理由曾经实施ISerializable,那么它可能是合理的,而实施变更意味着它不再有用。停止实施它可能是一个突破性的变化。

如果他们使用明确的实施方式(void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)而不是public void GetObjectData(SerializationInfo info, StreamingContext context)来实现它,并且拥有将SerializationInfoStreamingContext设为私有的构造函数,那么它就是一个破坏性较小的变化 - 在技术上仍然是一个突破性的变化,但实际上破坏任何实际用途的可能性要小得多。这本身就是将该构造函数设为私有的原因。

如果类没有被密封,它必须必须至少protected,并且派生类必须使用它,如果它们也是可序列化的。在这种情况下,停止使用它将彻底改变,因为所有派生类都会被破坏。

如果你没有实现它,那么同样会破坏变化,然后开始这样做,并从中派生出类。这可能是预防这种可能性的理由,但说实话,我认为这是YAGNI原则的一个重大失败,除非有一个非常好的理由怀疑它会变得有用。 (通常,如果你要添加一些必要的东西,你可以在另一个类中包含它所需的任何功能,在它上面实现它,并拥有该类型的成员,因此现有的类仍然可以在没有它的情况下进行序列化)。

编辑:上面的“必须”是“你必须这样做或者有不良影响”的“必须”,而不是“你必须做到这一点或它赢了”的“必须”编译“。当然,前者比后者更糟糕,因为你有时候可能做不到。

答案 2 :(得分:2)

你可能总是暗示ISerializable。是的,如果你有很多对象,可能会输入很多东西,但如果你以后引入它,反序列化程序会破坏。我认为对版本化对象更好,而不是编写新对象并保留旧对象。

答案 3 :(得分:1)

实现Iserializable可以提高性能,因为不需要使用反射来序列化对象

答案 4 :(得分:0)

需要签名构造函数(SerializationInfo信息,StreamingContext上下文)。反序列化时间。

答案 5 :(得分:0)

我看到,实现ISerializable对于这个类来说不是必需的。或者你必须添加一个带签名的构造函数(SerializationInfo信息,StreamingContext上下文): protected PersonName (SerializationInfo info, StreamingContext context){ this.NamePrefix = info.GetString("NamePrefix"); this.SurName = info.GetString("SurName"); this.GivenName = info.GetString("GivenName"); }