2011-12-05 112 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