强制(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() ?
您的帖子中有一个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/