强制(BinaryFormatter)序列化程序在ISerializable时使用SerializableAttribute语义?

时间:2011-08-17 07:03:56

标签: c# serialization

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

我测试的像这样的普通类

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

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

但是当它实现ISerialization或继承像Hashtable这样实现ISerialization的类时,你需要知道什么是反序列化构造函数。 “实现”这个词或概念变得用词不当,因为Hashtable实际上并没有实现那个构造函数。

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

2 个答案:

答案 0 :(得分:4)

您的帖子中存在 很多 的混淆:

  顺便说一句,prive和protected属性也会被序列化,尽管文档只说公开)

我怀疑你混淆了两个不同的序列化器; 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

  

有没有办法可以回退到仅由属性提供的“自动”序列化/反序列化?

没有;无。

  

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

对于继承数据,您可以链接基础构造函数或切换到封装而不是继承 - 或者避免担心除您自己以外的数据。

但请注意,我几乎总是引导BinaryFormatter - 它可能令人烦恼,并且对版本化很古怪。对于BinaryFormatter的每一个烦恼,我使用protobuf-net(我会,因为我写了它) - 这通常使序列化更加受控(并且更有效),并且包括{{{ 1}}如果你真的想要使用ISerializable(即它可以使用BinaryFormatter作为包装器,但使用protobuf-net有效负载),则会挂钩。

答案 1 :(得分:0)

Hashtable / Dictionary需要实现相应的方法......

要解决这个问题,你必须实现一个单独的类来保存Dictionary数据并提供一个IList接口,而这个接口又不需要在TKeyValuePair上工作,而是使用一个单独实现的Key / Value类(参考{{3 }})...
正如你从我的解释开始所看到的那样 - 这通常不是你想做的......

有更好的序列化解决方案 - 请参阅非常好的http://blogs.msdn.com/b/adam/archive/2010/09/10/how-to-serialize-a-dictionary-or-hashtable-in-c.aspx