I’m trying to replace our existing serialization with Proto-buf. Problem is we currently use ISerializable to check whether data has changed and only serialize the original value if the data has changed. This is done by using two nullable variables and only adding the original value in ISerializable.GetObjectData to the info object if the value has changed.
When deserializing, in the ISerializable constructor, I read the SerializationInfo to find which members were serialized and which ones were not. If an original value was not serialized, it’s value is set to the current value. (therefore saving resources as it wasn’t serialized).
Is there a way in Protobuf-net for me to find out what fields were deserialized? I am using the ShouldSerialize pattern to not send the original value as I explained above, but when I get to the other end I need to know what fields were serialized to be able to set the original value.
Edit: More Details, here is a sample class.
[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;
}
}
}
As you can see, _originalKey is not serialized if it has the same value as the _key. When the object is Deserialized, I want to know if _originalKey was Deserialized or not. I thought your answer of _originalKeySpecified would work, but in the class above, once I Deserialize, the _originalKeySpecified is always false. Does the Protobuf deserialization process set the value? (Note that I can’t use the ShouldSerialize property to decide whether to set the _originalKey when deserialized as it may have been changed from null to another value, which I need to know when saving in the data store.
It depends a bit on your specific case. For example, if you have nullable backing fields, then: the ones that were serialized are example the ones that have non-null values… i.e.
Here you could simply check each
ShouldSerialize*method to see which values were deserialized; anything that wasn’t will still havenull(it doesn’t call thesetif it didn’t have data to deserialize).An alternative is the
*Specifiedpattern, as used by some other serializers (XmlSerializer, IIRC – and possiblyDataContractSerializer). This is a simple bool property, which gets set (by the serializer) totrueif a value is assigned, but isn’t otherwise. Likewise, the value of*Specifiedis used identically toShouldSerialize*to determine whether a member should be processed during serialization.If I’ve missed your intent, please clarify (preferably with an example), and I’ll try to explain more.