1

既存のシリアル化を Proto-buf に置き換えようとしています。問題は、現在 ISerializable を使用してデータが変更されたかどうかを確認し、データが変更された場合にのみ元の値をシリアル化することです。これは、2 つの null 許容変数を使用し、値が変更された場合にのみ ISerializable.GetObjectData の元の値を情報オブジェクトに追加することによって行われます。

逆シリアル化するとき、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 はシリアル化されません。オブジェクトが Deserialized されている場合、_originalKey が Deserialized されているかどうかを知りたいです。_originalKeySpecified の答えはうまくいくと思いましたが、上記のクラスでは、Deserialize すると、_originalKeySpecified は常に false になります。Protobuf デシリアライゼーション プロセスは値を設定しますか? (データ ストアに保存するときに知る必要がある null から別の値に変更されている可能性があるため、デシリアライズ時に _originalKey を設定するかどうかを決定するために ShouldSerialize プロパティを使用できないことに注意してください。

4

1 に答える 1

0

それはあなたの特定のケースに少し依存します。たとえば、null許容のバッキングフィールドがある場合、次のようになります。シリアル化されたものは、null以外の値を持つものの例です...つまり

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

ShouldSerialize*ここでは、各メソッドをチェックして、どの値が逆シリアル化されたかを確認できます。存在しなかったものはすべて保持されますnullset(逆シリアル化するデータがない場合は、を呼び出しません)。

別の方法は、他のいくつかのシリアライザー( 、IIRC-および場合によっては)*Specifiedで使用されるパターンです。これは単純なboolプロパティであり、値が割り当てられているかどうかに(シリアライザーによって)設定されますが、そうでない場合は設定されません。同様に、の値は、シリアル化中にメンバーを処理する必要があるかどうかを決定するために同じように使用されます。XmlSerializerDataContractSerializertrue*SpecifiedShouldSerialize*

私があなたの意図を逃した場合は、明確にしてください(できれば例を挙げて)。もっと説明しようと思います。

于 2012-11-26T08:38:25.807 に答える