【问题标题】:Alternative to using Arrays and Redim Preserve使用 Arrays 和 Redim Preserve 的替代方案
【发布时间】:2015-02-26 17:16:13
【问题描述】:

我只有一个主要要求,那就是一切都是可序列化的。

我最初想将 List 和 Constructors 与可传递变量一起使用,这使一切看起来都很好,但后来发现它们都不容易序列化。

所以,目前我正在使用一个数组和ReDim Preserve,但是什么是存储多个项目并且仍然能够序列化它们的好方法?每次我走上一条路时,我似乎都会遇到限制/死胡同。

我有我的主类“MARKFILE”,它包含许多“标记”

Public Class MARKFILE
    Private _Name As String 
    Public ReadOnly Property Name
        Get
            Return _Name
        End Get
    End Property

    Public Property _Markers() As Marker()

  Public Sub Add_Marker(ByRef Aa As String, ByRef Bb As String, Cc As Double)
        Dim Mark As New Marker
        Mark.A= Aa 
        Mark.B= Bb 
        Mark.C= Cc 

       If IsNothing(_Markers) Then
            ReDim _Markers(0)
            _Markers(_Markers.Length - 1) = Mark
        Else
            ReDim Preserve _Markers(_Markers.Length)
            _Markers(_Markers.Length - 1) = Mark
        End If

    End Sub
End Class

Public Class Marker

    Public A As String
    Public B As String
    Public C As String
    Public D As String
End Class

【问题讨论】:

  • 一个列表不需要被序列化——它里面的数据虽然(标记)。你追求什么类型的序列化器?
  • 为什么不将 Public Property Marker 作为 List(Of Marker) ?
  • 你说的是设计师序列化还是对象序列化?
  • 老实说,任何类型的序列化,只要我可以轻松地将它保存到文件并加载它。我最熟悉 XML 序列化,也是我一直在尝试使用的。 @Plutonix 对象序列化我相信,我是所有存储的数据都被序列化到一个文件中

标签: .net arrays vb.net list serialization


【解决方案1】:

代码有很多问题,一开始就无法编译:

Public Sub Add_Marker(ByRef Aa As String, ByRef Bb As String, Cc As Double)
    ...
    Mark.C = Cc     ' Mark.C is String, cannot assign Double To String!

所以,首先打开 Option Strict。

要使List(of Marker) 可序列化,您需要添加一个属性:

<Serializable>
Public Class Marker
    Public Property A As String
    Public Property B As String
    Public Property C As String
    Public Property D As String
End Class

我也会使用属性(如图所示)而不是字段。集合类也需要该属性:

<Serializable>
Public Class Markers
    Private _Name As String
    Public ReadOnly Property Name As String
        Get
            Return _Name
        End Get
    End Property

    Public Property Markers As List(Of Marker)

    Public Sub New()
        Markers = New List(Of Marker)
    End Sub

    Public Sub Add(Aa As String, Bb As String, Cc As String)

        Markers.Add(New Marker With {.A = Aa, .B = Bb, .C = Cc})

    End Sub
End Class

序列化数据很简单:

Dim col As New Markers

col.Add("A", "B", "C")

Using fs As New FileStream("C:\temp\marks.bin", FileMode.OpenOrCreate)
    Dim bf As New BinaryFormatter
    bf.Serialize(fs, col)
End Using

您可能遇到的错误与List 无关,而是List 中的内容未标记为可序列化。


还有一些可以(应该)对集合类进行的改进。与其公开集合/列表,不如在其上添加、删除、清除、计数、项目等类型函数来实际管理列表,而不是仅仅持有它并将其公开给世界. Add 也可以重载以获取 Marker 对象。

名称属性似乎也应该在小数据类(标记)而不是集合上。因为它是(只读)它是无用的,因为没有办法设置它。

【讨论】:

  • 非常感谢!不知道“”。至于其他建议,我会遵循他们的!在找到将所有内容序列化的方法之前,我只是不想将所有内容放在一起。
  • 嘿,抱歉,只是一个简短的问题。您建议将列表设为私有并具有管理列表的功能。如何限制列表的曝光?据我了解,私有财产没有序列化?
  • 我可能实际上处理序列化的方式是作为作用于私有列表/集合的共享函数。然后,集合类似乎会自行序列化。您必须在某处传递文件名(我会使用 ctor)。此外,ProtoBuf-NET 是比 BF 更好的序列化程序,它可以处理私有成员。
  • xml序列化类只能序列化无参构造函数。使用构造函数传递一些东西不允许它序列化?
  • 对不起,是的,我一直在使用 XML,但我想我会试试你建议的 BinaryFormatter。我更喜欢 XML,但是当我通过构造函数传递参数时无法序列化。
猜你喜欢
  • 1970-01-01
  • 2016-09-16
  • 2010-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-07
相关资源
最近更新 更多