vb.net Сериализация / десериализация со ссылками - PullRequest
1 голос
/ 05 декабря 2011

У меня есть коллекция из 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 я могу иметь, например,20 предметов типа B. В col1 у меня есть, например, 2 предмета типа A. Каждый из них имеет n ссылок на предметы типа B на коллекцию col2.

Как я могу сериализовать и десериализовать эти объекты так, чтобыссылки будут восстановлены при десериализации?

Предпочтительная сериализация с 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

Это будет просто цикл по всем объектам A в col1, а затем цикл по всем объектам B и поиск объекта в col2 с тем же значением для myStringProp.

Значит, было бы полезно любое более чистое решение:)

Итак, какие-нибудь более чистые решения?

1 Ответ

2 голосов
/ 07 декабря 2011

Сериализатор может сохранять ссылки на объекты в одном эпизоде ​​сериализации . Таким образом, если у вас есть обе коллекции как члены одного объекта (который затем сериализуется / десериализуется), вы можете использовать параметр 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
...