空引用异常未处理

时间:2013-12-08 05:19:47

标签: vb.net exception reference null

这是一个非常简单的代码。我刚刚开始使用vb。我正在制作一个游戏,您可以将洗牌后的数字重新排序为正确的顺序。您尝试以最少的时间和最少的点击次数解决难题,下次玩游戏时,您会尝试获得较低的分数(或者击败该记录)。你有十六个按钮(4x4)和十五个数字。有一个checkbutton函数来查看拼图是否已解决每次调试程序时,它都会突出显示Clicks和FinalTime,并表示Null Reference Exception未处理。下面是一些代码。

Public Class Form1
Dim Clicks As Integer = 0  'The variable that counts the number of times you clicked
Dim Time As Integer 'The vairable that holds the time
Dim TimeMin As Integer 'The variable that holds the minutes
Dim TimeSec As Integer  'The variable that holds the seconds
Dim FinalTime As String 'The variable that holds the final time (minutes and seconds)
Dim lngArray() As String = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", ""} {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", ""}    
Dim NumArray() As Integer
Dim NumArray1() As String

Private Sub CheckButton(ByRef Butt1 As Button, ByRef Butt2 As Button)
    If Butt2.Text = "" Then 'Checks if the button around the clicked number is empty "" It's the location of the empty square that you want the number in Butt1 to move to.
        Butt2.Text = Butt1.Text 'If it is, the value from Butt2 will "copy and paste" into Butt1
        Butt1.Text = "" 'Butt1 will keep the value and the value in Butt2 will clear "" 
        Clicks += 1 'Incrementing Each click by only 1. It's a counter. In addition, the code above only allows the click to increment by 1 if the number has moved. If you just click on a number that can't move, the click would not count.
    End If
    If Clicks > 1 Then
        lblTotal.Text = Clicks & " Clicks" 'Shows the total amount of clicks when it is greater than one
    Else
        lblTotal.Text = Clicks & " Click" 'Shows the total amount of clicks when it is one
    End If

End Sub

Private Sub CheckSolved() 'A private sub that checks if the puzzle is solved ,restarts the count, and stops the time
    Dim strName As String = "" 'The variable that has the string of the winners name
    If Me.Button1.Text = "1" And Me.Button2.Text = "2" And Me.Button3.Text = "3" And Me.Button4.Text = "4" And Me.Button5.Text = "5" And Me.Button6.Text = "6" And Me.Button7.Text = "7" And Me.Button8.Text = "8" And Me.Button9.Text = "9" And Me.Button10.Text = "10" And Me.Button11.Text = "11" And Me.Button12.Text = "12" And Me.Button13.Text = "13" And Me.Button14.Text = "14" And Me.Button15.Text = "15" Then 'Checks if the numbers are in the correct buttons
        Timer1.Enabled = False 'Stops the time
        strName = InputBox("What is your name", "Name of winner") 'Get's the winners name 
        MessageBox.Show("In " & FinalTime & " , you solved the puzzle in " & Me.Clicks & " clicks! Congratulations " & strName) 'Messagebox showing how many times you clicked to solve the puzzle. It gets the name you typed into the inputbox (strname) and displays it
        Call Restart() 'Shuffles the buttons and restarts the game when you win
        Call Record(NumArray, NumArray1)
    End If
End Sub
Private Sub Record(ByVal NumArray() As Integer, ByVal NumArray1() As String)
    'Make timemin array and then make time array. Then make click array
    For i As Integer = 0 To 1000 
        NumArray(i) = Clicks 'This is where the Null Reference error occured
        i = +1
        Array.Sort(NumArray) 'sorting the array values from least to greatest
    Next i

    lblRecordClicks.Text = NumArray(0) & " Clicks" 'displaying the lowest number of clicks in the label
    For k As Integer = 0 To 1000 'Making an  integer that captures 1000 values
        NumArray1(k) = FinalTime 'This is where the Null Reference error occured
        k = +1
        Array.Sort(NumArray1) 'sorting the array values from least to greatest
    Next k

    lblRecordTime.Text = NumArray1(0) 'displaying the lowest time in the label
End Sub

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    Call Times()
End Sub

Private Sub Shuffle(ByVal lngArray As Object) 'Shuffles the values of the Array 
    Dim i As Long
    Dim iMin As Long
    Dim iMax As Long
    Dim lngReplace As Long
    Dim varSwap As Object
    iMin = LBound(lngArray)
    iMax = UBound(lngArray)
    For i = iMax To iMin + 1 Step -1
        lngReplace = Int((i - iMin + 1) * Rnd() + iMin)
        varSwap = lngArray(i)
        lngArray(i) = lngArray(lngReplace)
        lngArray(lngReplace) = varSwap
    Next
    Button1.Text = lngArray(0)
    Button2.Text = lngArray(1)
    Button3.Text = lngArray(2)
    Button4.Text = lngArray(3)
    Button5.Text = lngArray(4)
    Button6.Text = lngArray(5)
    Button7.Text = lngArray(6)
    Button8.Text = lngArray(7)
    Button9.Text = lngArray(8)
    Button10.Text = lngArray(9)
    Button11.Text = lngArray(10)
    Button12.Text = lngArray(11)
    Button13.Text = lngArray(12)
    Button14.Text = lngArray(13)
    Button15.Text = lngArray(14)
    Button16.Text = lngArray(15)
End Sub

Private Sub RestartToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RestartToolStripMenuItem.Click
    Call Restart()
    Call Me.btnStart_Click(sender, e) 'Call the button click to enable all buttons
End Sub
Private Sub Times()
    Time = Time + 1 'Increase the time by 1 second every interval
    TimeSec = TimeSec + 1 'Increase the time by 1 second every interval
    TimeMin = Convert.ToInt32(TimeSec \ 60) 'Takes the whole number of the amount of seconds divided by 60 and leaves out the remainder
    If Time >= 60 Then
        Time = 0
    End If
    'If the seconds pass 59 (and they do), it restarts to 0
    FinalTime = TimeMin & " min " & Time & " seconds" 'Final time is the string displayed showing the final time
    lblTime.Text = FinalTime 'The label displays the final time
End Sub
Private Sub Restart()
    Time = 0 'Resets the time
    Clicks = 0 'Resets the amount of clicks
    lblTotal.Text = "" 'Clears the label
    lblCheat.Visible = False
    lblTotal.Visible = True
    lblClicks.Visible = True
    lblQuote.Visible = True
    lblRecordClicks.Visible = True
    lblRecordTime.Visible = True
    'If the user cheated and hit the solve button and wants to restart and solve the puzzle on their own, then he can. Turning these label settings to true allows you to see them again
    Call Shuffle(lngArray) 'Shuffles the numbers
    Timer1.Enabled = True 'Continues the time when it resets to 0

End Sub

Public Sub RefreshEverythingToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RefreshEverythingToolStripMenuItem.Click
    Timer1.Enabled = False 'Pauses the timer
    If MessageBox.Show("Do you want to restart everything?", "Restart Game", MessageBoxButtons.YesNo, MessageBoxIcon.Information) = DialogResult.Yes Then
        Time = 0
        TimeSec = 0
        'Resets the time
        Clicks = 0 'Resets the amount of clicks
        lblTotal.Text = "" 'Clears the label
        lblRecordClicks.Text = "" 'Resets the record click
        lblRecordTime.Text = "" 'Resets the record time
    End If
    Call Shuffle(lngArray) 'Shuffles the numbers
    Timer1.Enabled = True 'Continues the timer if no is selected
    ReDim NumArray(1000) 'Clears the array data that was captured
    ReDim NumArray1(1000) 'Clears the array data that was captured
End Sub

End Class

如果您决定提供帮助(我希望您这样做),您可以尝试避免使用“计算机”谈话并尝试“为我愚蠢”。就像我之前说过的那样,我是新手。谢谢你的时间。

1 个答案:

答案 0 :(得分:0)

您正在尝试将值保存到数组中。当您定义像Dim NumArray() As Integer这样的数组时,没有为数组设置边界(数组基本上是Nothing),如果您尝试访问数组项,则会遇到Null引用异常。 您只需在Public Sub RefreshEverythingToolStripMenuItem_Click中设置数组范围。现在我不知道你的所有代码,但如果游戏是在没有用户专门点击这个按钮的情况下启动的,那么你的阵列将是Nothing。 您必须确保在游戏开始之前始终设置数组边界。

您还可以在.NET中查看更抽象的类似数组的类型。例如,您可以尝试列表。 List实际上是一个具有任意边界的数组。使用Of关键字定义具有特定类型的List,然后可以使用Add方法,删除项目,对列表进行排序等列表向其中添加项目。

定义为全局变量:

Dim FinalTimes as New List(Of Integer)
Dim FinalClicks as New List(Of Integer)

确保在此处使用New关键字。这意味着将创建类List的新对象。否则,您将再次在下面的行中遇到Null Reference Exceptions。 当用户解决谜题时,您可以:

FinalTimes.Add(FinalTime)
FinalClicks.Add(Clicks)
FinalTimes.Sort
FinalClicks.Sort

这将基本上将列表的长度增加一个,将FinalTime / Clicks值写入最后一个项目,然后选择两个列表。想法:对于高分,您可能希望将FinalTime,Clicks和Player Name连接到结构中,并使用IComparer接口让用户按名称/时间/点击对高分列表进行排序。

PS:在我忘记之前:你的代码中出现异常的For循环没有任何意义。第一个问题是,在它们当前的形式中,它们将是无限循环,因为你总是在循环中将i设置为1,而当i = 1000时循环结束(这显然不会发生)。我认为你的意思是i=i+1或更短i += 1。但他们仍然没有多大意义。我试着看看究竟发生了什么(这不明显:-)),你的一半高分被新值等覆盖。我认为上面的方法会更容易。 : - )