2011-12-05 110 views
1

我有一個2個不同的對象集合。vb.net序列化/反序列化引用

比方說,我有以下兩個對象

Private col1 as Collection(Of A)Private col2 as Collection(Of B)

但A型的對象具有B型的集合作爲屬性。

所以A看起來像

Public Class A 
    Public Property myStringProp() as string 
    Public Property colB() as Collection(Of B) 
End Class 

而乙看起來像

Public Class B 
    Public Property myStringProp() as string 
End Class 

所以在COL2我可以有例如B型有20件。 在col1中,例如,類型A的2個項目。它們中的每一個對col2的集合具有n個對類型B的項目的引用。

我如何序列化和反序列化對象,這些使得引用將反序列化時,可以恢復?

使用XML的首選序列化。

我曾嘗試使用DataContractSerializer的,但我不知道在哪裏以及如何使用它。

編輯:

確定。我將能夠手動解決它們。但我不喜歡的方式:

For Each itema As A In col1 
    For Each itemb As B In itema.colB 
     For Each objB In col2 
      If itemb.myStringProp = objB.myStringProp Then 
       itemb = objB 
      End If 
     Next 
    Next 
    Next 

這只是通過COL1 A的所有對象循環,然後遍歷B的所有對象,並在COL2與myStringProp相同值搜索的對象。

因此,任何清晰的解決方案,將不勝感激:)

因此,任何清潔的解決方案?

回答

2

串行器可以在單個序列化片段中保留對象引用。所以,如果你有兩個集合作爲單個對象的成員(這被串行化/反序列化),則可以使用preserveObjectReferences參數的構造函數DataContractSerializer,你就會明白了。另一種選擇是用<DataContract(IsReference:=True)>來修飾類型,該類型也可以用來保存參考。下面的代碼顯示了第一種方法。

Public Class StackOverflow_8387789 
    Public Class A 
     Public Property myStringProp() As String 
     Public Property colB() As Collection(Of B) 
    End Class 

    Public Class B 
     Public Property myStringProp() As String 
    End Class 

    Public Class Both 
     Public Property col1 As Collection(Of A) 
     Public Property col2 As Collection(Of B) 
    End Class 

    Public Shared Sub Test() 
     Dim both = New Both() 
     both.col2 = New Collection(Of B) 
     both.col2.Add(New B With {.myStringProp = "B1"}) 
     both.col2.Add(New B With {.myStringProp = "B2"}) 
     both.col2.Add(New B With {.myStringProp = "B3"}) 
     both.col1 = New Collection(Of A) 
     Dim colBForA1 = New Collection(Of B) 
     colBForA1.Add(both.col2(0)) 
     colBForA1.Add(both.col2(1)) 
     Dim colBForA2 = New Collection(Of B) 
     colBForA2.Add(both.col2(1)) 
     colBForA2.Add(both.col2(2)) 
     both.col1.Add(New A With {.myStringProp = "A1", .colB = colBForA1}) 
     both.col1.Add(New A With {.myStringProp = "A2", .colB = colBForA2}) 
     Dim dcs = New DataContractSerializer(GetType(Both), Nothing, Integer.MaxValue, False, True, Nothing) 
     Dim ms = New MemoryStream() 
     Dim ws = New XmlWriterSettings With { _ 
       .Encoding = Encoding.UTF8, 
       .Indent = True, 
       .IndentChars = " ", 
       .OmitXmlDeclaration = True 
      } 
     Dim xw = XmlWriter.Create(ms, ws) 
     dcs.WriteObject(xw, both) 
     xw.Flush() 
     Console.WriteLine("Serialized: {0}", Text.Encoding.UTF8.GetString(ms.ToArray())) 

     ms.Position = 0 
     Console.WriteLine("Now deserializing:") 
     Dim both2 = CType(dcs.ReadObject(ms), Both) 
     Console.WriteLine("Is both.col1(0).colB(0) = both.col2(0)? {0}", both2.col1(0).colB(0) Is both2.col2(0)) 
     Console.WriteLine("Is both.col1(1).colB(1) = both.col2(2)? {0}", both2.col1(1).colB(1) Is both2.col2(2)) 
     Console.WriteLine("Is both.col1(0).colB(0) = both.col2(2) (should be False)? {0}", both2.col1(0).colB(0) Is both2.col2(2)) 
    End Sub 
End Class 
+0

這就是我一直在尋找。謝謝 :) – Nicholas