2013-09-25 64 views
4

今天我一直在使用protobuf-net,並且遇到了一個奇怪的情況。下面的代碼不會按預期反序列化。最後兩個反序列化嘗試成功,但它們不正確。反序列化的對象的IsEmpty設置爲true,實際上它應設置爲false。我已經能夠通過私人設置器來獲得序列化的屬性,但這個行爲是不正確的。它與鏈式默認構造函數有關嗎?protobuf-net沒有序列化與私人setter的C#屬性

class Program2 
{ 
    static void Main(string[] args) 
    { 
     var comp = new FooComparer(); 

     // this deserializes fine. woot! 
     using (var ms = new MemoryStream()) 
     { 
      Console.WriteLine("Serializing an empty Foo"); 
      var args1 = new Foo(); 
      Serializer.Serialize(ms, args1); 
      ms.Position = 0; 
      var result = Serializer.Deserialize(ms); 
      Console.WriteLine("Serialization successful: {0}", comp.Equals(args1, result)); 
      Console.WriteLine(); 
     } 

     // this deserializes incorrectly 
     using (var ms = new MemoryStream()) 
     { 
      Console.WriteLine("Serializing a Foo with just a string"); 
      var args1 = new Foo("576000BJ1"); 
      Serializer.Serialize(ms, args1); 
      ms.Position = 0; 
      var result = Serializer.Deserialize(ms); 
      Console.WriteLine("Serialization successful: {0}", comp.Equals(args1, result)); 
      Console.WriteLine(); 
     } 

     // this deserializes incorrectly 
     using (var ms = new MemoryStream()) 
     { 
      Console.WriteLine("Serializing a Foo with an int"); 
      var args1 = new Foo(42); 
      Serializer.Serialize(ms, args1); 
      ms.Position = 0; 
      var result = Serializer.Deserialize(ms); 
      Console.WriteLine("Serialization successful: {0}", comp.Equals(args1, result)); 
      Console.WriteLine(); 
     } 

     Console.WriteLine("Got dat 190% serialization"); 
    } 
} 

[ProtoContract] 
class Foo 
{ 
    private Foo(bool isEmpty, string fooString, int? fooInt) 
    { 
     this.IsEmpty = isEmpty; 
     this.FooString = fooString; 
     this.FooInt = fooInt; 
    } 

    public Foo() : this(true, null, null) { } 
    public Foo(string foo) : this(false, foo, null) { } 
    public Foo(int foo) : this(false, null, foo) { } 

    [ProtoMember(10)] public bool IsEmpty { get; private set; } 
    [ProtoMember(20)] public string FooString { get; private set; } 
    [ProtoMember(30)] public int? FooInt { get; private set; } 
} 

class FooComparer : IEqualityComparer 
{ 
    public bool Equals(Foo x, Foo y) 
    { 
     return (x == null && y == null) || 
       (x != null && y != null && 
       x.IsEmpty == y.IsEmpty && 
       String.Equals(x.FooString, y.FooString, StringComparison.Ordinal) && 
       x.FooInt == y.FooInt); 
    } 

    public int GetHashCode(Foo obj) { return 1; } // don't care about this 
}

編輯: 我使用.NET 3.5的protobuf 2.0.0.666

回答

2

在這裏找到了答案:c# protobuf-net when deserialize the some property value always is -1

爲了節省空間,protobuf的不值類型序列化的默認值。 在此示例中,bool的.NET默認值爲false。默認構造函數將IsEmpty屬性設置爲true,並且由於我期望它的值與.NET默認值相同,protobuf跳過保存該值,所以我從默認構造函數中獲取該值。

修復方法是將IsRequired設置爲TRUE,如Marc所述,或者對參數使用[ProtoContract(10), DefaultValue(true)]

2

這是隱含的默認值行爲。最簡單的解決方法可能是用IsRequired = true(屬性屬性)標記IsEmpty。

相關問題