vb.net使用引用序列化/反序列化

时间:2011-12-05 15:37:23

标签: vb.net serialization xml-serialization deserialization

我有两个不同的对象集合。

假设我有以下两个对象

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

而B看起来像

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

所以在col2中我可以有例如20件B型 在col1我有例如A类中的2项。每个项目都有对B类集合的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的所有对象,并使用myStringProp的相同值搜索col2中的对象。

所以任何更清洁的解决方案都会受到赞赏:)

那么任何更清洁的解决方案?

1 个答案:

答案 0 :(得分: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