强制(BinaryFormatter)序列化器在可序列化时使用SerializableAttribute语义

本文关键字:序列化 语义 SerializableAttribute BinaryFormatter 强制 | 更新日期: 2023-09-27 18:05:43

我正在尝试学习使用c#序列化作为一种将对象保存到可以重新加载回对象的文件的方法。

我测试的一个像这样的普通类

[Serializable()]
public class PlainClass
{
    public string Name;
    private int Age;
    protected decimal Price;
}

可以直接使用BinaryFormatter.Serialize()和BinaryFormatter.Deserialize()而不会出错。(顺便说一下,私有和受保护的属性也被序列化,尽管文档说只有公共)

但是当它实现序列化或继承一些实现序列化的类(如Hashtable)时,就需要反序列化构造函数。"实现"这个词或概念变得用词不当,因为Hashtable实际上并没有实现该构造函数。

是否有办法退回到仅由属性提供的"自动"序列化/反序列化?或者是否有一种更简单的方法来为一个类中的100个属性编写info.GetValue() ?

强制(BinaryFormatter)序列化器在可序列化时使用SerializableAttribute语义

您的帖子中有一个lot混乱:

顺便说一下,private和protected属性也被序列化了尽管文档说只有public)

我怀疑你混淆了两个不同的序列化器;BinaryFormatter一直以领域为中心。它不区分公共/私有,也从不查看属性:只查看字段。相比之下,XmlSerializer只查看公共属性和字段。

"实现"这个词或概念变得名不符实,因为Hashtable实际上并没有实现该构造函数。

是的,它有;它是一个protected构造函数:

protected Hashtable(SerializationInfo info, StreamingContext context)
{...}

如果你继承了Hashtable,你可以链接到这个构造函数:

protected YourType(SerializationInfo info, StreamingContext context)
     : base(info, context)
{ /* your extra data */ }

但是,请注意,除非您使用。net 1.1,否则您可能不应该过多地使用Hashtable

是否有办法退回到仅由属性提供的"自动"序列化/反序列化?

没有;没有。

或者是否有一种更简单的方法来为一个类中的100个属性编写info.GetValue() ?

在继承数据的情况下,您可以链接基构造函数或切换到封装而不是继承—两者都可以避免担心您自己以外的数据。

但是,请注意,我几乎总是反对BinaryFormatter -它可能令人烦恼,并且在版本控制方面很奇怪。对于BinaryFormatter的每一个烦恼,我使用protobuf-net(我会,因为我写了它)-这通常使序列化更控制(和更有效),并包括一个ISerializable钩子,如果你真的想要使用BinaryFormatter(即它可以使用BinaryFormatter作为包装器,但有一个protobuf-net负载)。

哈希表/字典需要实现各自的方法…

要解决这个问题,你必须实现一个单独的类来保存Dictionary数据,并提供一个IList接口,而不是在TKeyValuePair上工作,而是使用一个单独实现的具有Key/Value的类(参见http://blogs.msdn.com/b/adam/archive/2010/09/10/how-to-serialize-a-dictionary-or-hashtable-in-c.aspx)…
正如你可以从我的解释开始看到的——这不是你通常想要做的……

有更好的序列化解决方案,请参阅一个非常好的http://code.google.com/p/protobuf-net/