在一类中存储和恢复二维数组

时间:2019-03-21 12:26:10

标签: arrays vb.net multidimensional-array

我最近刚从VB6移到VB.NET,并且正在重新编码旧的应用程序。因此,到目前为止,我对.NET还是一无所知。

我有多个(在本代码示例中为4)二维字符串数组(或实际上是数组数组),我想将其存储为ComboBox项。一维数组是一项。

Public Class MyItem

    Private sName As String
    Private sArr As Array()

    Public Sub New(ByVal Name As String, ParamArray Arr As Array())
        sName = Name
        sArr = Arr
    End Sub

    Public Property Arr() As Array()
        Get
            Return sArr
        End Get

        Set(ByVal sValue As Array())
            sArr = sValue
        End Set
    End Property

    Public Overrides Function ToString() As String
        Return sName
    End Function

End Class

---

Dim sMyArray as Array()

For i As Integer = 0 to 3
    sMyArray = Nothing   ' resetting the array before refilling it
    '
    ' No code here but filling sMyArray by reading a text file, each line
    ' number as dim 1 and splitted each line into dim 2 with ";" using Split(sRead, ";")
    ' so Debub.Print(sMyArray(0)(0)) prints the beginning of the first line until first ";" <- this works fine
    '
    ' Then passing sMyArray to a ComboBox item
    ' 
    ComboBox.Items.Add(New MyItem("item" & i, sMyArray))
Next i

问题是,从ComboCox项恢复阵列时,只有最后一个ComboBox项具有阵列数据。例如

Dim sMyNewArray As Array() = ComboBox.Items.Item(0).Arr
Debug.Print(sMyNewArray(0)(0))

时引发错误
Dim sMyNewArray As Array() = ComboBox.Items.Item(3).Arr
Debug.Print(UBound(sMyNewArray(UBound(sMyNewArray))))

不执行,并打印最后一项的最后一行的ubound

任何人都可以找出我所缺少的是什么,或者告诉我一种更好的方法吗?我很确定有一个..

2 个答案:

答案 0 :(得分:2)

我不确定100%,但是我认为问题出在此部分:

Dim sMyArray as Array()

For i As Integer = 0 to 3
    sMyArray = Nothing   ' resetting the array before refilling it

数组在技术上是引用类型,但是像字符串一样,还有一些额外的编译器魔术使它们有时更像是值类型,在这种情况下,我有一种感觉是使用了实际的sMyArray引用(也许是因为ParamArrays的最佳化),因此将其设置为Nothing会破坏事情。像这样为.Net编写此代码的更惯用的方法:

For i As Integer = 0 to 3
    Dim sMyArray as Array()

.Net具有比VB6更复杂的垃圾收集器。我们不再经常将变量设置为Nothing,而只是重新分配它们或让它们超出范围。实际上,在极少数情况下,将变量设置为Nothing可能会非常有害。此外,我们希望在循环内看到Dim关键字,因此您正在每次迭代中使用不同变量,且范围要尽可能小。

虽然我在这里,但是在.Net中,我们几乎从不使用基Array类型。代替这个:

Private sArr As Array()

您几乎总是执行此操作:

Private arr As String()()
对于真正的二维(非锯齿状)数组,

或这样:

Private arr As String(,)

或者,最重要的是,

Private arr As New List(Of String())

由于VB.Net具有比数组更多的集合类型。

此外,我没有可用的链接,但是Microsoft的编码准则现在明确要求您使用匈牙利疣作为变量和类名(因此sArr可以{ {1}})。这是VB6时代的变化,因为更改了语言,在语言中类型更可能由变量隐含,并对工具进行了改进,前缀通常不再增加太多的实用性,并且已显示出损害可读性的特点。 / p>

答案 1 :(得分:0)

不太确定为什么要使用二维数组,但这是一个不使用Array类型的小样本。它仅使用纯字符串和字符串数组。让我知道是否有帮助。这将拆分几个字符串,然后在填充后读出结果。

Public Class Form1



    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim sMyArray()() As String

        Dim line1 As String = "a;b;c;d 1;2;3;4;5"
        Dim line2 As String = "z;x;y;w 99;65;32;21;18"

        sMyArray = ParseString(line1)
        cboBox1.Items.Add(New MyItem("System0", sMyArray))

        sMyArray = ParseString(line2)
        cboBox1.Items.Add(New MyItem("System1", sMyArray))

        For i As Integer = 0 To cboBox1.Items.Count - 1

            For j As Integer = 0 To UBound(cboBox1.Items(i).arr)
                For k As Integer = 0 To UBound(cboBox1.Items(i).arr(j))
                    Debug.Write(cboBox1.Items(i).arr(j)(k) & " ")
                Next

            Next
            Debug.WriteLine("")
        Next

    End Sub

    Private Function ParseString(s As String) As String()()
        Dim rows As String() = s.Split(" ")
        Dim matrix As String()() = New String(rows.Length - 1)() {}

        For i As Integer = 0 To rows.Length - 1
            matrix(i) = rows(i).Split(";")
        Next

        Return matrix

    End Function
End Class

Public Class MyItem

    Private sName As String
    Private sArr As String()()


    Public Sub New(ByVal Name As String, ByVal ParamArray Arr As String()())
        sName = Name
        sArr = Arr
    End Sub

    Public Property Arr() As String()()
        Get
            Return sArr
        End Get

        Set(ByVal sValue As String()())
            sArr = sValue
        End Set
    End Property

    Public Overrides Function ToString() As String
        Return sName
    End Function

End Class