3

これに気付かないうちに、この問題がバグなのか、それともこれだけなのかわかりません。

クラスを作成Documentし、protobuf-net制限を宣言します。

[ProtoContract]
public class Document
{
    [ProtoMember(1)]
    private Dictionary<string,string> _items;

    [ProtoMember(2)]
    public int DocNumber
    {
        get;
        set;
    }

    public Document()
    {
        this.DocNumber = -1;
        this._items = new Dictionary<string,string>();    
    }

    public byte[] Serialize()
    {
        byte[] bytes = null;
        using (var ms = new MemoryStream())
        {
            Serializer.Serialize(ms, this);
            bytes = ms.ToArray();
            ms.Close();
        }
        return bytes;           
    }

    public static Document Deserialize(byte[] bytes)
    {
        Document obj = null;
        using (var ms = new MemoryStream(bytes))
        {
            obj = Serializer.Deserialize<Document>(ms);
            ms.Close();
        }
        return obj;
    }
 }

テストコードで:

  var doc = new Document();
  doc.DocNumber = 0;          
  var bytes = doc.Serialize();
  var new_doc = Document.Deserialize(bytes);
  Console.WriteLine(new_doc.DocNumber + " vs " + doc.DocNumber);

出力メッセージは次のとおりです-1 vs 0。。私はこの結果を信じることができません(正しい結果は0 vs 0)、したがって、に変更する doc.DocNumber = 0doc.DocNumber = 1、出力は正しいです:1 vs 1

この問題は、プロパティにゼロを割り当てることができないことを意味しDocNumberます。ドキュメントの構築メソッドで、DocNumberプロパティが-1であることを宣言する必要があります。

誰かが私を助けることができますか?この問題は私の原因ですか、それともprotobuf-netの原因ですか?ありがとう。

4

2 に答える 2

3

ProtoBufは、タイプの.NETデフォルトを持つ値をシリアル化しません。この動作は、出力をよりコンパクトにするため、仕様によるものです。

コンストラクターがデフォルト値をフィールドに割り当てることを知らないため、-1に初期化されます(これを行うための明示的なコードがあるため)。

この問題を回避するには、コンストラクターでデフォルトを割り当てるのではなく、通常のフィールドを使用してデフォルト値を割り当てます。

于 2012-05-06T04:16:10.627 に答える
3

デフォルトでは。デフォルトとしてゼロ値を想定しています。この設計の選択を後悔しているので、v2で無効にすることができますが、互換性のために保持されています。v1とv2の両方で、-1がデフォルトであることを単に伝えることもできます。

[ProtoMember(2), DefaultValue(-1)]
public int DocNumber
于 2012-05-06T07:53:09.553 に答える