Protobuf-net - 啥被序列化了?
Posted
技术标签:
【中文标题】Protobuf-net - 啥被序列化了?【英文标题】:Protobuf-net - what was serialized?Protobuf-net - 什么被序列化了? 【发布时间】:2012-11-26 03:18:23 【问题描述】:我正在尝试用 Proto-buf 替换我们现有的序列化。问题是我们目前使用 ISerializable 来检查数据是否已更改,如果数据已更改,则仅序列化原始值。这是通过使用两个可为空的变量来完成的,并且如果值已更改,则仅将 ISerializable.GetObjectData 中的原始值添加到 info 对象。
反序列化时,在 ISerializable 构造函数中,我读取了 SerializationInfo 以查找哪些成员已序列化,哪些未序列化。如果原始值未序列化,则将其值设置为当前值。 (因此节省了资源,因为它没有被序列化)。
Protobuf-net 中有没有办法让我找出哪些字段被反序列化了?如上所述,我使用 ShouldSerialize 模式不发送原始值,但是当我到达另一端时,我需要知道哪些字段被序列化才能设置原始值。
编辑:更多细节,这里是一个示例类。
[Serializable()]
[ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
public class SomeClass : ISerializable
internal int? _key;
internal int? _originalKey;
internal bool ShouldSerialize_key()
return _key.HasValue;
[NonSerialized]
public bool _keySpecified;
internal bool ShouldSerialize_originalKey()
return _key != _originalKey;
[NonSerialized]
public bool _originalKeySpecified;
[OnDeserialized()]
internal void OnDeserializedMethod(StreamingContext context)
// Use this to set the _originalKey if it hasn't been specified.
if (!_originalKeySpecified)
_originalKey = _key;
如您所见,如果_originalKey 与_key 具有相同的值,则它不会被序列化。当对象被反序列化时,我想知道 _originalKey 是否被反序列化。我认为您对 _originalKeySpecified 的回答会起作用,但在上面的课程中,一旦我反序列化,_originalKeySpecified 总是错误的。 Protobuf 反序列化过程是否设置了值? (请注意,我无法使用 ShouldSerialize 属性来决定是否在反序列化时设置 _originalKey,因为它可能已从 null 更改为另一个值,我需要在保存到数据存储区时知道这一点。
【问题讨论】:
重新编辑:请参阅我的回答中的措辞:“这是一个简单的 bool 属性...” -_originalKeySpecified
不是 bool 属性,所以不是匹配它正在寻找的模式。 _keySpecified
也不是属性,请注意。
另外,请注意它不使用 both 模式:它查找 *Specified
属性,然后查找 ShouldSerialize*
方法,然后停止。所以基本上你也会把你的一些其他逻辑移到*Specified
。这个顺序是因为*Specified
允许get
和set
(分别); ShouldSerialize*
实际上只是 get
,所以是第二选择。
啊facepalm。正如您在下面所说,它还必须是公开的。为什么它不能设置为内部工作?
hmmm...它应该作为内部/私有工作; ShouldSerialize*
确实如此(我刚刚测试过) - 我会看看为什么稍后不起作用
找到并修复;致力于源,但我还没有部署 NuGet 等
【参考方案1】:
这取决于您的具体情况。例如,如果您有可为空的支持字段,那么:被序列化的字段是具有非空值的示例......即
private int? id;
[ProtoMember(n)]
public int Id
get return id.GetValueOrDefault();
set id = value;
public bool ShouldSerializeId() return id.HasValue;
在这里您可以简单地检查每个ShouldSerialize*
方法以查看哪些值被反序列化;任何不是的东西仍然会有null
(如果它没有要反序列化的数据,它不会调用set
)。
另一种选择是*Specified
模式,它被其他一些序列化程序使用(XmlSerializer
、IIRC - 可能还有DataContractSerializer
)。这是一个简单的 bool 属性,如果分配了值,则(由序列化程序)将其设置为 true
,否则不会。同样,*Specified
的值与ShouldSerialize*
的使用相同,用于确定是否应在序列化期间处理成员。
如果我错过了您的意图,请澄清(最好用一个例子),我会尝试解释更多。
【讨论】:
我在上面添加了更多细节。以上是关于Protobuf-net - 啥被序列化了?的主要内容,如果未能解决你的问题,请参考以下文章