我最近刚从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
任何人都可以找出我所缺少的是什么,或者告诉我一种更好的方法吗?我很确定有一个..
答案 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