[英]vb.net Object Array Losing Values - Handling a collection of objects
我希望下面是完整的代码。
Q1:为什么两次调试写入产生不同的值?
第一个Debug Write可以正确执行,但是第二个Debug Write显示数组中的每个对象与在For Each循环中创建的最后一个对象具有相同的值。
问题2:除了数组以外,还有更好的方法来处理对象集合吗?
最后的测试值。
谢谢你的帮助。
码:
Public Class Form1
Public facilities() As Facility
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim FileToImport As String = GetFileName("Select Facility Import File")
Dim facility As New Facility
Dim counter As Integer = 0
Dim words() As String
Dim i As Integer
'Sample line format: FacID<TAB>FacSingleChar<TAB>ParentFacID
Try
If File.Exists(FileToImport) Then
For Each line As String In File.ReadLines(FileToImport)
words = line.Split(vbTab)
With facility
.FacilityID = words(0)
.FacilitySingleCharID = words(1)
.ParentFacilityID = words(2)
End With
ReDim Preserve facilities(counter)
facilities(counter) = facility
Debug.WriteLine("First Print: " & facilities(i).FacilityID & vbTab & facilities(i).ParentFacilityID & facilities(i).FacilitySingleCharID)
counter = counter + 1
Next line
For i = 1 To facilities.GetUpperBound(0)
Debug.WriteLine("Second Print: " & facilities(i).FacilityID & vbTab & facilities(i).ParentFacilityID & facilities(i).FacilitySingleCharID)
Next
End If
Catch ex As Exception
MsgBox(ex.Message & vbTab & ex.ToString)
End Try
End Sub
Private Function GetFileName(ByVal DialogTitle As String, Optional ByVal FileFilter As String = "All Files (*.*)|*.*") As String
Dim oDlg As New OpenFileDialog()
Dim FileName As String = ""
Try
With oDlg
.Title = DialogTitle
.Filter = FileFilter
.ShowDialog()
FileName = .FileName
End With
Return FileName
Catch ex As Exception
Return ""
End Try
End Function
End Class
Public Class Facility
Private m_FacilityID As String = Space(4)
Private m_ParentFacilityID As String = Space(4)
Private m_FacilitySingleCharID As String = Space(1)
Public Property FacilityID As String
Get
Return m_FacilityID
End Get
Set(ByVal value As String)
m_FacilityID = value.PadRight(4)
End Set
End Property
Public Property ParentFacilityID As String
Get
Return m_ParentFacilityID
End Get
Set(ByVal value As String)
m_ParentFacilityID = value.PadRight(4)
End Set
End Property
Public Property FacilitySingleCharID As String
Get
Return m_FacilitySingleCharID
End Get
Set(ByVal value As String)
If Len(value) = 1 Then
m_FacilitySingleCharID = value
Else
m_FacilitySingleCharID = "?"
End If
End Set
End Property
End Class
导入文件的测试数据:
导入文件应具有3个制表符分隔的列:
(条目之间不应有空格,这是使它们在此处可读的唯一方法)
APC A NCT
BAB B NCT
BABG C NCT
CCR D NCT
这里有几个问题在起作用。
最直接的是在第二个打印循环中,For..Next循环索引变量i
以1
作为起始值,应为0。
第二个比较复杂。
您将创建一个新的设施对象,并且每次循环都要为该对象分配新的值,并将该对象分配给数组中新创建的最后一个元素。
问题在于对象如何工作以及如何使用它们
每次循环时,您只需将新值分配给同一对象,然后将该对象存储在数组的每个元素中。 但是,代码在后台执行的操作并不是每次都使用新值存储新对象,而是在每个元素中存储对同一对象的引用,并在每次循环中更改值。 这就是为什么数组中所有值都相同的原因。
您需要做的就是移动生产线
Dim facility As New Facility
进入循环,以便在每次通过循环时创建一个新对象
像这样
For Each line As String In File.ReadLines(FileToImport)
Dim facility As New Facility
words = line.Split(vbTab.ToCharArray)
With facility
.FacilityID = words(0)
.FacilitySingleCharID = words(1)
.ParentFacilityID = words(2)
End With
ReDim Preserve facilities(counter)
facilities(counter) = facility
Debug.WriteLine("First Print: " & facilities(counter).FacilityID & vbTab & facilities(counter).ParentFacilityID & facilities(counter).FacilitySingleCharID)
counter = counter + 1
Next line
最初,对象可能会令人困惑,但请看一下引用类型和值类型以及变量范围。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.