2011-12-05 15 views
1

私は様々なオブジェクトの2つのコレクションを持っています。vb.net参照でシリアライズ/デシリアライズ

のは、私は、次の2つのオブジェクト

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

しかし、タイプAのオブジェクトは属性として、タイプBのコレクションを持っているとしましょう。

ので、AがBに

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

ように見える一方、そうCOL2に、私は、例えば持つことができる

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

ように見えますタイプBの20個のアイテム。 タイプAの2つのアイテム。それぞれ、タイプBのアイテムに対する参照がcol2のコレクションに対してn個あります。

デシリアライズ時に参照が復元されるように、これらのオブジェクトを直列化および逆直列化する方法はありますか?

XMLによる優先シリアル化

私はDataContractSerializerを使用しようとしましたが、どこでどのように使用するかわかりません。

編集:

OK。私はそれらを手動で解決することができます。しかし、私は道を好きではない:

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内のオブジェクトを検索します。

だから、どのクリーナー解決策をいただければ幸いです:)

だから、任意のクリーナーソリューションを?

答えて

2

シリアライザは、オブジェクト参照を1つのシリアル化エピソードに保存できます。したがって、両方のコレクションを単一のオブジェクトのメンバ(シリアル化/逆シリアル化されたもの)として使用している場合は、DataContractSerializerコンストラクタでpreserveObjectReferencesパラメータを使用できます。もう1つの選択肢は、タイプを<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

関連する問題