2014-01-06 39 views
0

在以下代碼中,有2個靜態狀態:初始狀態和最後狀態。當Test類首先被創建時,它會以InitialStatus的狀態被創建。此狀態可以通過單獨的呼叫(ChangeStatus)進行更改。Protobuf-Net似乎重用了現有對象,而不是創建並分配新對象

當我創建的TestClass的對象,並改變其狀態,然後原序列化和反序列化對象時,它看起來像它將覆蓋InitialStatus值。所以Protobuf本質上似乎重用了一個現有的對象,如果有一個對象在解序列化數據時可用的話。 (但是,如果對象爲空,它不會那樣做)。有什麼方法可以自定義此行爲,以便在反序列化後,對象將被重構而不是重用現有變量?

[ProtoContract] 
public class Status 
{ 
    private static Status _initialStatus; 
    public static Status InitialStatus 
    { 
     get{ 
      if (_initialStatus == null) 
      { 
       _initialStatus = new Status{StatusId=-1}; 
      } 
      return _initialStatus; 
     } 
    } 

    private static Status _lastStatus; 
    public static Status LastStatus 
    { 
     get{ 
      if (_lastStatus == null) 
      { 
       _lastStatus = new Status{StatusId=-2}; 
      } 
      return _lastStatus; 
     } 
    } 

    [ProtoMember(101)] 
    public int StatusId{get; private set;} 
} 

[ProtoContract] 
public class TestClass2 
{ 
    public TestClass2() 
    { 
     Initialize(); 
    } 

    private void Initialize() 
    { 
     CurrentStatus = Status.InitialStatus; 
    } 

    [ProtoMember(101)] 
    public Status CurrentStatus{get; private set;} 

    public void ChangeStatus(Status newStatus) 
    { 
     CurrentStatus = newStatus; 
    } 
} 


void Main() 
{ 
    TestClass2 test = new TestClass2(); 

    test.ChangeStatus(Status.LastStatus); 


    string serializedTest = ProtoUtils.Serialize(test); 
    TestClass2 testDeserialized = ProtoUtils.Deserialize<TestClass2>(serializedTest); 

    Debug.Assert(Status.InitialStatus.StatusId == -1, "Initial Status has changed"); 
    Debug.Assert(Status.LastStatus.StatusId == -2, "Last Status has changed"); 
} 


public static class ProtoUtils 
{ 
    public static string Serialize(Object o) 
    { 
     String result = String.Empty; 

     using (MemoryStream stream = new MemoryStream()) 
     { 
      Serializer.Serialize(stream, o); 

      result = Convert.ToBase64String(stream.ToArray()); 
     } 
     result.Dump(); 
     return result; 
    } 

    public static T Deserialize<T>(string data) 
    { 
     T result = default(T); 

     if (data != null) 
     { 
      byte[] dataBytes = Convert.FromBase64String(data); 

      using (Stream stream = new MemoryStream(dataBytes)) 
      { 
       result = Serializer.Deserialize<T>(stream); 
      } 

     } 

     return result; 
    } 
} 
+0

嗨,你可以提供'ProtoUtils'的代碼,所以我ca ñ測試這在我的目的? –

回答

1

選項:

  • 上ProtoContractAttribute指定SkipConstructor - 這將防止在場地對象創建過程中被初始化
  • 使用前 - 反序列化回調(實例方法裝飾有適當的屬性)並擦領域 - 這發生在施工後,但在它讀取數據之前
+0

我應該在我的問題中指定這個,但我不能跳過構造函數。主要是因爲在我的實際代碼中,構造函數確實做了一些我不能跳過的工作。我希望不使用回調。 –

+0

@RajRao個人我仍然會使用跳過的構造函數和回調的組合(以完全運行所需的代碼) - 但是如何定製工廠呢?我沒有提到的第三個選項是你可以通過使用靜態方法來創建實例,然後以任何你喜歡的方式來初始化protobuf-net –

相關問題