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

本文关键字:实现 接口 ISerializable 反序列化 任何 自定义 序列化 | 更新日期: 2023-09-27 18:20:45

我正在研究实现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接口。这是正确的吗?

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

该类实际上一开始就不需要实现ISerializable接口。这是正确的吗?

正确。当您需要执行默认序列化行为之外的其他操作时,才可以实现ISerializable[Serializable]属性应该足够了。

这毫无意义。

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

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

如果类不是密封的,则它必须至少为protected,如果派生类也要串行化,则派生类必须使用它。在这种情况下,停止使用它将是一个彻底的破坏性更改,因为所有派生类都将被破坏。

如果你不实现它,然后开始实现它,并从中派生类,这同样会破坏变革。这可能是先发制人的理由,但老实说,我认为这是YAGNI原则的一个重大失败,除非有非常好的理由怀疑它会变得有用。(通常,如果你要添加一些必要的东西,你可以将需要它的任何功能包装在另一个类中,在这个类上实现它,并拥有该类型的成员,这样现有的类仍然可以在没有它的情况下串行化)。

编辑:上面的"must"是"你必须这样做,否则会有不良影响"的"必须",而不是"你必须这么做,否则它不会编译"的"必然"。当然,前者比后者更糟糕,因为有时你可能做不到。

您不妨始终实现ISerializable。是的,如果你有很多对象,这可能需要很多类型,但如果你稍后引入反序列化程序,它会崩溃。我认为它更适合对对象进行版本控制,而不是编写新对象并保留旧对象。

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

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

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