VB.net,引用对不同私有子中的私有子中的 public 变量所做的更改

VB.net, Referencing changes made to public variables in a private sub within a different private subs

在我程序的一个私有子程序 (openFile_Click) 中,我更改了我在 Public class 中调暗的变量,称为名称、距离和点。但是当我尝试从另一个私人子 (btnGameEnter) 重新打印它们时,它们是空白的。我知道在测试之后变量在 openFile sub 中被正确设置,并且不知道为什么在 openFile sub 中完成的相同过程将变量添加到列表框,但在 btnGameEnter sub 中不起作用,变量应该在哪里已经有来自 openFile 的数据。

Public Class frmdetails


    Dim Names(100) As String
    Dim Distance(100, 2) As String
    Dim Points(100, 2) As String

    Private Sub openFile_Click(sender As Object, e As EventArgs) Handles openFile.Click
        OpenFileDialog.ShowDialog()
        Dim strFileName = OpenFileDialog.FileName
        Dim objReader As New System.IO.StreamReader(strFileName)
        Dim textline As String


        lstNames.Items.Clear()
        lstDistance.Items.Clear()
        lstPoints.Items.Clear()

        Dim Count As Integer = 0


        Do While objReader.Peek() <> -1

            textline = objReader.ReadLine() & vbNewLine

            Dim parts() As String = textline.Split("|")

            Names(Count) = parts(0)
            Distance(Count, 0) = parts(1)
            Distance(Count, 1) = parts(2)
            Distance(Count, 2) = parts(3)
            Points(Count, 0) = parts(4)
            Points(Count, 1) = parts(5)
            Points(Count, 2) = parts(6)

            Count = Count + 1


        Loop

        For n = 0 To Count - 1
            lstNames.Items.Add(Names(n))
            lstNames.Items.Add(" ")
            lstDistance.Items.Add(Distance(n, 0) + " Miles")
            lstDistance.Items.Add(" ")
            lstPoints.Items.Add(Points(n, 0))
            lstPoints.Items.Add(" ")
        Next

    End Sub

    Private Sub btnGameEnter_Click(sender As Object, e As EventArgs) Handles btnGameEnter.Click

        Dim ChosenGame As Integer = 0
        Dim Count As Integer = 0

        ChosenGame = cboWhichGame.Text

        lstGameNum.Items.Clear()

        lstNames.Items.Clear()
        lstDistance.Items.Clear()
        lstPoints.Items.Clear()

        lstGameNum.Items.Add(ChosenGame)


        For n = 0 To Count - 1
            lstNames.Items.Add(Names(n))
            lstNames.Items.Add(" ")
            lstDistance.Items.Add(Distance(n, (ChosenGame - 1)) + " Miles")
            lstDistance.Items.Add(" ")
            lstPoints.Items.Add(Points(n, (ChosenGame - 1)))
            lstPoints.Items.Add(" ")
        Next

    End Sub
End Class

我发现了这些问题:

  1. BtnGameEnter_Click 中,您将局部变量初始化为 Dim Count As Integer = 0。它的值永远不会改变。这意味着 for 循环永远不会执行。将其设为 class 字段,而不是在所有订阅者之间共享它(并从两个订阅者中删除 Dim Count)。

    Public Class frmReferencingFields
        Dim Count As Integer = 0
        ....
    
  2. 您应该初始化 ChosenGame,这是一个 IntegercboWhichGame.SelectedIndex,第一个游戏将是 0。所以加的时候不要减1。这允许您将说话的名字添加到 ComboBox 而不是裸数字。

    Dim ChosenGame As Integer = cboWhichGame.SelectedIndex
    ...
    lstDistance.Items.Add(Distance(n, ChosenGame) + " Miles")
    lstPoints.Items.Add(Points(n, ChosenGame))
    

此外,我不确定您是否为距离和点选择了正确的类型。它们真的是字符串吗?


我提出另一种方法。名称、距离和点是否代表位置?它假设它。所以让我们创建一个 Location class

Public Class Location
    Property Name As String
    Property Distance As Double
    Property Points As Integer
End Class

您似乎有 3 场比赛。因此,让我们以

的形式创建一个这样的游戏数组
Dim game(2) As List(Of Location)

游戏数量是固定的,因为它取决于文件格式。每个游戏都包含可变数量的位置。最好为此使用 List(Of T),因为它会自动增长以适应内容。

另外,让我们添加一个方便的例程,将游戏添加到列表中。我们可以在两个 Sub 中重复使用它。

Private Sub DisplayGame(game As List(Of Location))
    lstNames.Items.Clear()
    lstDistance.Items.Clear()
    lstPoints.Items.Clear()
    For Each location As Location In game
        lstNames.Items.Add(location.Name)
        lstNames.Items.Add(" ")
        lstDistance.Items.Add(location.Distance & " Miles")
        lstDistance.Items.Add(" ")
        lstPoints.Items.Add(location.Points.ToString())
        lstPoints.Items.Add(" ")
    Next
End Sub

请注意我们如何使用单个变量 game As List(Of Location) 和一个位置 location As Location 来表示游戏,而不必处理单独的名称、距离和点数数组。此外,不需要单独的 Count 变量,因为列表会自动跟踪计数。

现在,两个 Sub 变成了

Private Sub OpenFile_Click(sender As Object, e As EventArgs) Handles openFile.Click
    OpenFileDialog.ShowDialog()
    Dim strFileName = OpenFileDialog.FileName

    'Create the lists
    For i As Integer = 0 To UBound(game)
        game(i) = New List(Of Location)()
    Next i

    For Each textline As String In File.ReadLines(strFileName)
        Dim parts() As String = textline.Split("|"c)

        If parts.Length = 7 Then 'Not an empty line
            For g As Integer = 0 To UBound(game)
                Dim location = New Location()
                location.Name = parts(0)
                location.Distance = CDbl(parts(1 + g))
                location.Points = CInt(parts(4 + g))
                game(g).Add(location)
            Next g
        End If
    Next

    DisplayGame(game(0))
End Sub

Private Sub BtnGameEnter_Click(sender As Object, e As EventArgs) Handles btnGameEnter.Click
    Dim ChosenGame As Integer = cboWhichGame.SelectedIndex

    lstGameNum.Items.Clear()
    lstGameNum.Items.Add(ChosenGame)
    DisplayGame(game(ChosenGame))
End Sub