我正在尝试学习使用C#序列化作为将对象保存到可以重新加载回对象的文件的方法。
我测试的像这样的普通类
[Serializable()]
public class PlainClass
{
public string Name;
private int Age;
protected decimal Price;
}
可以直接使用BinaryFormatter.Serialize()和BinaryFormatter.Deserialize()而不会出错。 (顺便说一下,私有和受保护的属性也会被序列化,尽管文档只说公开)
但是当它实现ISerialization或继承像Hashtable这样实现ISerialization的类时,你需要知道什么是反序列化构造函数。 “实现”这个词或概念变得用词不当,因为Hashtable实际上并没有实现那个构造函数。
有没有办法回退到仅由属性提供的“自动”序列化/反序列化?或者是否有更简单的方法为类中的一百个属性写入info.GetValue()?
答案 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