Serialisieren von komplexen Zahlen

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Serialisieren von komplexen Zahlen

    Hallo Leute,
    in meinem derzeitigen Projekt habe ich in einem Vektorraum eine Liste an komplexen Zahlen. Ich möchte also die Klasse "[Object]", welche eine "List(Of VectorSpace)" besitzt, welche wiederum die Eigenschaft "List(Of Complex)" besitzt, abspeichern. Zum Serialisieren verwende ich normal immer diese Funktionen:

    VB.NET-Quellcode

    1. Public Shared Sub WriteObjects(ByVal path As String, ByVal obj As List(Of [Object]))
    2. Using objStreamWriter As New StreamWriter(path)
    3. Dim x As New XmlSerializer(obj.GetType)
    4. x.Serialize(objStreamWriter, obj)
    5. End Using
    6. End Sub
    7. Public Shared Function ReadObjects(ByVal path As String) As List(Of [Object])
    8. Dim obj As New List(Of [Object])
    9. Using objStreamReader As New StreamReader(path)
    10. Dim x As New XmlSerializer(obj.GetType)
    11. obj = CType(x.Deserialize(objStreamReader), List(Of [Object]))
    12. End Using
    13. Return obj
    14. End Function


    Funktioniert soweit auch, nur, dass wenn ich die Datei wieder einlese alle Vektorräume leer sind. Wenn ich die Datei nach dem serialisieren öffne, sieht sie so aus:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <ArrayOfObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    3. <Object>
    4. <VectorSpace>
    5. <Vectors>
    6. <Complex />
    7. <Complex />
    8. <Complex />
    9. <Complex />
    10. <Complex />
    11. <Complex />
    12. <Complex />
    13. <Complex />
    14. <Complex />
    15. <Complex />
    16. <Complex />
    17. <Complex />
    18. <Complex />
    19. <Complex />
    20. <Complex />
    21. <Complex />
    22. <Complex />
    23. <Complex />
    24. <Complex />
    25. <Complex />
    26. <Complex />
    27. <Complex />
    28. </Vectors>
    29. </VectorSpace>
    30. <Name>H</Name>
    31. </Object>
    32. <Object>
    33. <VectorSpace>
    34. <Vectors>
    35. <Complex />
    36. <Complex />
    37. <Complex />
    38. <Complex />
    39. <Complex />
    40. <Complex />
    41. <Complex />
    42. <Complex />
    43. <Complex />
    44. <Complex />
    45. <Complex />
    46. <Complex />
    47. <Complex />
    48. <Complex />
    49. </Vectors>
    50. </VectorSpace>
    51. <Name>A</Name>
    52. </Object>
    53. <Object>
    54. <VectorSpace>
    55. <Vectors>
    56. <Complex />
    57. <Complex />
    58. <Complex />
    59. <Complex />
    60. <Complex />
    61. <Complex />
    62. <Complex />
    63. <Complex />
    64. <Complex />
    65. <Complex />
    66. <Complex />
    67. <Complex />
    68. <Complex />
    69. <Complex />
    70. </Vectors>
    71. </VectorSpace>
    72. <Name>L</Name>
    73. </Object>
    74. <Object>
    75. <VectorSpace>
    76. <Vectors>
    77. <Complex />
    78. <Complex />
    79. <Complex />
    80. <Complex />
    81. <Complex />
    82. <Complex />
    83. <Complex />
    84. <Complex />
    85. <Complex />
    86. <Complex />
    87. <Complex />
    88. <Complex />
    89. <Complex />
    90. <Complex />
    91. </Vectors>
    92. </VectorSpace>
    93. <Name>L</Name>
    94. </Object>
    95. <Object>
    96. <VectorSpace>
    97. <Vectors>
    98. <Complex />
    99. <Complex />
    100. <Complex />
    101. <Complex />
    102. <Complex />
    103. <Complex />
    104. <Complex />
    105. <Complex />
    106. <Complex />
    107. <Complex />
    108. <Complex />
    109. <Complex />
    110. </Vectors>
    111. </VectorSpace>
    112. <Name>O</Name>
    113. </Object>
    114. </ArrayOfObject>



    Wie man sieht sind alle komplexen Zahlen leer. Die Klasse Complex ist nicht von mir sondern von System.Numerics. Weiß jemand, was ich falsch mache? Sollte ich lieber eine eigene Complex-Klasse machen?

    mfG Frank
    Ich glaube das liegt daran, dass Complex nur Get-Only Eigenschaften hat, aber: ​Die XML-Serialisierung ist die Konvertierung der öffentlichen Eigenschaften und Felder eines Objekts in ein serielles Format (in diesem Fall XML), also nur Eigenschaften die Get und Set public haben. Muss es denn XML sein? Der BinaryFormatter sollte das können.
    Ja, danke das wars :D
    Wusste gar nichts von anderen Serialisier-Arten ?(
    So hab ich's nun gemacht:

    VB.NET-Quellcode

    1. Public Shared Sub WriteObjects(ByVal path As String, ByVal objs As List(Of [Object]))
    2. Dim bf As New BinaryFormatter
    3. bf.Serialize(New FileStream(path, FileMode.Create), objs)
    4. End Sub
    5. Public Shared Function ReadObjects(ByVal path As String) As List(Of [Object])
    6. Dim bf As New BinaryFormatter
    7. Return CType(bf.Deserialize(New FileStream(path, FileMode.Open)), List(Of [Object]))
    8. End Function


    mfG Frank
    Funkst einwandfrei

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Option Explicit On
    3. Imports System.Numerics
    4. Imports System.Runtime.Serialization
    5. Module Module1
    6. Sub Main()
    7. Beispiel()
    8. End Sub
    9. Private Sub Beispiel()
    10. Dim cn1 As New List(Of ComplexNumber) From {New ComplexNumber(13.1, 15.2), _
    11. New ComplexNumber(9.0, 7.8), _
    12. New ComplexNumber(21.1, 16.6), _
    13. New ComplexNumber(42.2, 33.2)}
    14. Dim cn2 As New List(Of ComplexNumber) From {New ComplexNumber(13.1, 15.2), _
    15. New ComplexNumber(9.0, 7.8), _
    16. New ComplexNumber(21.1, 16.6), _
    17. New ComplexNumber(42.2, 33.2)}
    18. Dim cn3 As New List(Of ComplexNumber) From {New ComplexNumber(13.1, 15.2), _
    19. New ComplexNumber(9.0, 7.8), _
    20. New ComplexNumber(21.1, 16.6), _
    21. New ComplexNumber(42.2, 33.2)}
    22. Dim vs1 As New VectorSpace2
    23. vs1.add(cn1)
    24. vs1.add(cn2)
    25. vs1.add(cn3)
    26. SaveXml(vs1, "data.txt")
    27. Dim vs As New VectorSpace2
    28. LoadXml(vs, "data.txt")
    29. Stop
    30. End Sub
    31. Private Sub SaveXml(Of T)(ByVal obj As T, ByVal file As String)
    32. Using fs As New IO.FileStream(file, IO.FileMode.OpenOrCreate)
    33. Dim xmlSer As New Xml.Serialization.XmlSerializer(GetType(T))
    34. xmlSer.Serialize(fs, obj)
    35. fs.Flush()
    36. End Using
    37. End Sub
    38. Private Sub LoadXml(Of T)(ByRef obj As T, ByVal file As String)
    39. Using fs As New IO.FileStream(file, IO.FileMode.OpenOrCreate)
    40. Dim xmlSer As New Xml.Serialization.XmlSerializer(GetType(T))
    41. obj = DirectCast(xmlSer.Deserialize(fs), T)
    42. End Using
    43. End Sub
    44. End Module
    45. <Serializable()> _
    46. Public Class VectorSpace2
    47. Private mVs As New List(Of ComplexNumber())
    48. Public Property VS() As List(Of ComplexNumber())
    49. Get
    50. Return mVs
    51. End Get
    52. Set(ByVal value As List(Of ComplexNumber()))
    53. mVs = value
    54. End Set
    55. End Property
    56. Public Sub add(ByVal cn As List(Of ComplexNumber))
    57. mVs.Add(cn.ToArray)
    58. End Sub
    59. Public Sub New()
    60. End Sub
    61. End Class
    62. ''' <summary>
    63. ''' Complex number.
    64. ''' </summary>
    65. <Serializable()> _
    66. Public Structure ComplexNumber
    67. Public Re As Double
    68. Public Im As Double
    69. 'https://www.vb-paradise.de/index.php/Thread/90280-Komplexe-Zahlen-in-Visual-Basic/?postID=747363#post747363
    70. Public Sub New(ByVal re As Double)
    71. Me.Re = re : Me.Im = 0
    72. End Sub
    73. Public Sub New(ByVal re As Double, ByVal im As Double)
    74. Me.Re = re : Me.Im = im
    75. End Sub
    76. Public Shared Operator *(ByVal n1 As ComplexNumber, ByVal n2 As ComplexNumber) As ComplexNumber
    77. Return New ComplexNumber(n1.Re * n2.Re - n1.Im * n2.Im, n1.Im * n2.Re + n1.Re * n2.Im)
    78. End Operator
    79. Public Shared Operator +(ByVal n1 As ComplexNumber, ByVal n2 As ComplexNumber) As ComplexNumber
    80. Return New ComplexNumber(n1.Re + n2.Re, n1.Im + n2.Im)
    81. End Operator
    82. Public Shared Operator -(ByVal n1 As ComplexNumber, ByVal n2 As ComplexNumber) As ComplexNumber
    83. Return New ComplexNumber(n1.Re - n2.Re, n1.Im - n2.Im)
    84. End Operator
    85. Public Shared Operator -(ByVal n As ComplexNumber) As ComplexNumber
    86. Return New ComplexNumber(-n.Re, -n.Im)
    87. End Operator
    88. Public Shared Widening Operator CType(ByVal n As Double) As ComplexNumber
    89. Return New ComplexNumber(n, 0)
    90. End Operator
    91. Public Function PoweredE() As ComplexNumber
    92. Dim e As Double = Math.Exp(Re)
    93. Return New ComplexNumber(e * Math.Cos(Im), e * Math.Sin(Im))
    94. End Function
    95. Public Function Power2() As Double
    96. Return Re * Re - Im * Im
    97. End Function
    98. Public Function AbsPower2() As Double
    99. Return Re * Re + Im * Im
    100. End Function
    101. Public Overrides Function ToString() As String
    102. Return [String].Format("{0}+i*{1}", Re, Im)
    103. End Function
    104. End Structure


    Edit: Sorry ich hab gar nicht aktualisiert, und nicht gesehen das schon eine Antwort abgegeben wurde.
    Edit2: Korrigiert - Danke für den Hinweis @Bluespide


    Hinweis: Manchmal ist es sehr sinnvoll die bestehende Datei vorher zu löschen. File.Delete("data.txt")

    Freundliche Grüsse

    exc-jdbi

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „exc-jdbi“ ()

    @xd-franky-5 Serialisiere nicht einzelne Datenelemente, sondern Instanzen von Daten-Klassen. Alle deren Properties werden (de-)serialisiert.
    Der Code sieht praktisch identisch aus. Das funktioniert sogar so gut, dass Versionsänderungen (alte Properties weg, neue Properties dazu) gut deswerialisieret werden.
    Gugst Du hier.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!