【问题标题】:vb.net Serialize/Deserialize with referencesvb.net 序列化/反序列化与引用
【发布时间】:2011-12-05 15:37:23
【问题描述】:

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

假设我有以下两个对象

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 我可以有例如B型20件。 在 col1 我有例如类型 A 的 2 项。它们中的每一项都有对 col2 集合的类型 B 的 n 项的引用。

如何序列化和反序列化这些对象,以便在反序列化时恢复引用?

首选 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 的对象。

所以任何更清洁的解决方案将不胜感激:)

那么有更清洁的解决方案吗?

【问题讨论】:

    标签: vb.net serialization xml-serialization deserialization


    【解决方案1】:

    序列化程序可以在单个序列化情节中保留对象引用。因此,如果您将两个集合都作为单个对象的成员(然后对其进行序列化/反序列化),则可以在DataContractSerializer 构造函数中使用preserveObjectReferences 参数,您将得到它。另一种选择是用<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
    

    【讨论】:

    • 这就是我想要的。谢谢:)
    猜你喜欢
    • 2022-01-02
    • 2011-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-25
    • 1970-01-01
    相关资源
    最近更新 更多