1

我正在尝试用 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 更改为另一个值,我需要在保存到数据存储时知道这一点。

4

1 回答 1

0

这取决于您的具体情况。例如,如果您有可为空的支持字段,那么:被序列化的字段是具有非空值的示例......即

private int? id;
[ProtoMember(n)]
public int Id {
    get { return id.GetValueOrDefault(); }
    set { id = value; }
}
public bool ShouldSerializeId() { return id.HasValue; }

在这里,您可以简单地检查每个ShouldSerialize*方法以查看哪些值被反序列化;没有的东西仍然有nullset(如果它没有要反序列化的数据,它不会调用)。

另一种选择是*Specified模式,正如其他一些序列化程序(XmlSerializer,IIRC - 和可能DataContractSerializer)所使用的那样。这是一个简单的 bool 属性,如果分配了一个值,它会(由序列化程序)设置true,否则不会。同样, 的值同样*Specified用于ShouldSerialize*确定是否应在序列化期间处理成员。

如果我错过了您的意图,请澄清(最好用一个例子),我会尝试解释更多。

于 2012-11-26T08:38:25.807 回答