1

我正在用 Visual Basic .NET 编写这个程序来组织不同的数据字段,并且我正在通过应用程序设置使用配置文件槽来为用户存储数据。但是,我在SlotSelect.vb课堂上遇到了堆栈溢出错误。对于为什么会发生这种情况,我最好的合理猜测是我在下面的酱汁代码中使用了错误类型的变量容器,但我的困境是我不知道具体出了什么问题。

vshost 所说的导致溢出的代码是从我在 MSDN 和其他地方查找的一些代码中编写的,用于引用其他类中的对象,我尝试使用它的其他变体来查看它是否有任何不同. 到目前为止,没有任何效果,并且它不会在编译时停止错误,更不用说在代码标记中了——它只有在完成构建后在调试中启动应用程序时才会捕获它。

这是酱汁代码SlotSelect.vb。由于大多数其他不相关的类(和这个类)都导致了MainForm.vb,我也将包括它的酱汁。vshost 给出的位置,因为错误位于_MainForm定义要Flaglister.MainForm在 中使用的变量的行上SlotSelect.vb

插槽选择.vb

Public Class SlotSelect

    ' Class variables
    Private _MainForm As Flaglister.MainForm = New Flaglister.MainForm
    Private _SaveSlot As Flaglister.SaveSlot = New Flaglister.SaveSlot
    Private _Misc As Flaglister.Misc = New Flaglister.Misc
    Private _FlagsTextBox As System.Windows.Forms.TextBox = Flaglister.MainForm.FlagsTextBox
    Private _VarsTextBox As System.Windows.Forms.TextBox = Flaglister.MainForm.VarsTextBox
    Private _HackNameTextBox As System.Windows.Forms.TextBox = Flaglister.MainForm.HackNameTextBox
    Private _RomCodeTextBox As System.Windows.Forms.TextBox = Flaglister.MainForm.RomCodeTextBox
    Private _NotesTextBox As System.Windows.Forms.TextBox = Flaglister.MainForm.NotesTextBox
    Private _ExpandedCheckBox As System.Windows.Forms.CheckBox = Flaglister.MainForm.ExpandedCheckBox

    ' Slot selection main execution subs
    Friend Sub _0()
        Try
            ' Disable FlagsTextBox
            _FlagsTextBox.DeselectAll()
            _FlagsTextBox.ClearUndo()
            _FlagsTextBox.Clear()
            _FlagsTextBox.Enabled = False
            ' Disable VarsTextBox
            _VarsTextBox.DeselectAll()
            _VarsTextBox.ClearUndo()
            _VarsTextBox.Clear()
            _VarsTextBox.Enabled = False
            ' Disable HackNameTextBox
            _HackNameTextBox.DeselectAll()
            _HackNameTextBox.ClearUndo()
            _HackNameTextBox.Clear()
            _HackNameTextBox.Enabled = False
            ' Disable RomCodeTextBox
            _RomCodeTextBox.DeselectAll()
            _RomCodeTextBox.ClearUndo()
            _RomCodeTextBox.Clear()
            _RomCodeTextBox.Enabled = False
            ' Disable NotesTextBox
            _NotesTextBox.DeselectAll()
            _NotesTextBox.ClearUndo()
            _NotesTextBox.Clear()
            _NotesTextBox.Enabled = False
        Catch
            Call _Misc.ErrorClose()
        End Try
    End Sub
    Friend Sub _1()
        Try
            ' Load flaglist
            _FlagsTextBox.DeselectAll()
            _FlagsTextBox.ClearUndo()
            _FlagsTextBox.Clear()
            _FlagsTextBox.Enabled = True
            _FlagsTextBox.Text = My.Settings.Flaglist_1
            ' Load varlist
            _VarsTextBox.DeselectAll()
            _VarsTextBox.ClearUndo()
            _VarsTextBox.Clear()
            _VarsTextBox.Enabled = True
            _VarsTextBox.Text = My.Settings.Varlist_1
            ' Load project name
            _HackNameTextBox.DeselectAll()
            _HackNameTextBox.ClearUndo()
            _HackNameTextBox.Clear()
            _HackNameTextBox.Enabled = True
            _HackNameTextBox.Text = My.Settings.Hackname_1
            ' Load ROM codename
            _RomCodeTextBox.DeselectAll()
            _RomCodeTextBox.ClearUndo()
            _RomCodeTextBox.Clear()
            _RomCodeTextBox.Enabled = True
            _RomCodeTextBox.Text = My.Settings.Romcode_1
            ' Load other notes
            _NotesTextBox.DeselectAll()
            _NotesTextBox.ClearUndo()
            _NotesTextBox.Clear()
            _NotesTextBox.Enabled = True
            _NotesTextBox.Text = My.Settings.Notes_1
        Catch
            Call _Misc.ErrorClose()
        End Try
    End Sub
    Friend Sub _2()
        Try
            ' Load flaglist
            _FlagsTextBox.DeselectAll()
            _FlagsTextBox.ClearUndo()
            _FlagsTextBox.Clear()
            _FlagsTextBox.Enabled = True
            _FlagsTextBox.Text = My.Settings.Flaglist_2
            ' Load varlist
            _VarsTextBox.DeselectAll()
            _VarsTextBox.ClearUndo()
            _VarsTextBox.Clear()
            _VarsTextBox.Enabled = True
            _VarsTextBox.Text = My.Settings.Varlist_2
            ' Load project name
            _HackNameTextBox.DeselectAll()
            _HackNameTextBox.ClearUndo()
            _HackNameTextBox.Clear()
            _HackNameTextBox.Enabled = True
            _HackNameTextBox.Text = My.Settings.Hackname_2
            ' Load ROM codename
            _RomCodeTextBox.DeselectAll()
            _RomCodeTextBox.ClearUndo()
            _RomCodeTextBox.Clear()
            _RomCodeTextBox.Enabled = True
            _RomCodeTextBox.Text = My.Settings.Romcode_2
            ' Load other notes
            _NotesTextBox.DeselectAll()
            _NotesTextBox.ClearUndo()
            _NotesTextBox.Clear()
            _NotesTextBox.Enabled = True
            _NotesTextBox.Text = My.Settings.Notes_2
        Catch
            Call _Misc.ErrorClose()
        End Try
    End Sub
    Friend Sub _3()
        Try
            ' Load flaglist
            _FlagsTextBox.DeselectAll()
            _FlagsTextBox.ClearUndo()
            _FlagsTextBox.Clear()
            _FlagsTextBox.Enabled = True
            _FlagsTextBox.Text = My.Settings.Flaglist_3
            ' Load varlist
            _VarsTextBox.DeselectAll()
            _VarsTextBox.ClearUndo()
            _VarsTextBox.Clear()
            _VarsTextBox.Enabled = True
            _VarsTextBox.Text = My.Settings.Varlist_3
            ' Load project name
            _HackNameTextBox.DeselectAll()
            _HackNameTextBox.ClearUndo()
            _HackNameTextBox.Clear()
            _HackNameTextBox.Enabled = True
            _HackNameTextBox.Text = My.Settings.Hackname_3
            ' Load ROM codename
            _RomCodeTextBox.DeselectAll()
            _RomCodeTextBox.ClearUndo()
            _RomCodeTextBox.Clear()
            _RomCodeTextBox.Enabled = True
            _RomCodeTextBox.Text = My.Settings.Romcode_3
            ' Load other notes
            _NotesTextBox.DeselectAll()
            _NotesTextBox.ClearUndo()
            _NotesTextBox.Clear()
            _NotesTextBox.Enabled = True
            _NotesTextBox.Text = My.Settings.Notes_3
        Catch
            Call _Misc.ErrorClose()
        End Try
    End Sub


    ' Save all slots
    Friend Sub SlotSaveAll()
        Call _SaveSlot.FlaglistSave()
        Call _SaveSlot.VarlistSave()
        Call _SaveSlot.HacknameSave()
        Call _SaveSlot.RomcodeSave()
        Call _SaveSlot.NotesSave()
        Call _SaveSlot.ExpandedSave()
    End Sub
End Class

主窗体.vb

Public Class MainForm

    ' Class-level variables
    Private _SlotSelect As New Flaglister.SlotSelect
    Private _SaveSlot As New Flaglister.SaveSlot
    Private _Misc As New Flaglister.Misc

    ' Startup/Shutdown events
    Sub MainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        If Slot0RadioButton.Checked = True Then
            Call _SlotSelect._0()
        End If
    End Sub
    Sub MainForm_Deactivate(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Deactivate
        My.Settings.Save()
        Me.Close()
    End Sub

    ' Form object events
    Private Sub Slot0RadioButton_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Slot0RadioButton.CheckedChanged
        If Slot0RadioButton.Checked = True Then
            Call _SlotSelect._0()
        End If
    End Sub
    Private Sub Slot1RadioButton_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Slot1RadioButton.CheckedChanged
        If Slot1RadioButton.Checked = True Then
            Call _SlotSelect._1()
        End If
    End Sub
    Private Sub Slot2RadioButton_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Slot2RadioButton.CheckedChanged
        If Slot2RadioButton.Checked = True Then
            Call _SlotSelect._2()
        End If
    End Sub
    Private Sub Slot3RadioButton_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Slot3RadioButton.CheckedChanged
        If Slot3RadioButton.Checked = True Then
            Call _SlotSelect._3()
        End If
    End Sub
    Private Sub FlagsTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FlagsTextBox.TextChanged
        Call _SaveSlot.FlaglistSave()
    End Sub
    Private Sub VarsTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles VarsTextBox.TextChanged
        Call _SaveSlot.VarlistSave()
    End Sub
    Private Sub HackNameTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles HackNameTextBox.TextChanged
        Call _SaveSlot.HacknameSave()
    End Sub
    Private Sub RomCodeTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RomCodeTextBox.TextChanged
        Call _SaveSlot.RomcodeSave()
    End Sub
    Private Sub NotesTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NotesTextBox.TextChanged
        Call _SaveSlot.NotesSave()
    End Sub
    Private Sub ExpandedCheckBox_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExpandedCheckBox.CheckedChanged
        Call _SaveSlot.ExpandedSave()
    End Sub
End Class

代码中有什么问题?

这里有一些关于我和我的程序的额外细节。

电脑

系统:7 x64 w/ AMD Sempron
编译器:Microsoft Visual Basic 2010 Express

应用

框架:Microsoft .NET 3.5 版
根名称空间:Flaglister
程序集名称:Flaglister
应用程序类型:Windows 窗体应用程序

有时我想太多,所以如果答案对很多人来说是显而易见的而我没有看到,我很抱歉。

编辑

这是抛出错误时调用堆栈在其当前位置的屏幕截图,以及弹出错误框的另一个屏幕截图。我从来没有想过要添加这些。

调用堆栈截图

异常截图

4

3 回答 3

3

这里的问题是递归初始化。MainForm包含:

Private _SlotSelect As New Flaglister.SlotSelect

SlotSelect包含:

Private _MainForm As Flaglister.MainForm = New Flaglister.MainForm

他们不断调用对方的构造函数,导致你的堆栈溢出。您可以通过在的构造函数中_MainForm作为参数传入来解决此问题。SlotSelect像这样:

Public Class SlotSelect

    ' Class variables
    Private _MainForm As Flaglister.MainForm
    ' (truncated for space)

    Public Sub New(ByVal mainForm As Flaglister.MainForm)
        Me._MainForm = mainForm
    End Sub

    '...

在 中,将当前实例MainForm.vb传递给构造函数:SlotSelect

Private _SlotSelect As New Flaglister.SlotSelect(Me)
于 2012-06-07T02:48:02.100 回答
2

我猜这是因为在您的课程中您正在声明和实例化 MainForm 的新实例

 Private _MainForm As Flaglister.MainForm = New Flaglister.MainForm

然后在 MainForm 类中声明和实例化 SlotSelect 类的新实例

 Private _SlotSelect As New Flaglister.SlotSelect

所以这两个类只是“反弹”来回创建彼此的新实例,最终给你堆栈溢出。

于 2012-06-07T02:48:33.727 回答
0

您处于无限循环中。

在 slotselect 你有

Private _MainForm As Flaglister.MainForm = New Flaglister.MainForm

它创建一个新的主窗体,然后在 MainForm 你有

Private _SlotSelect As New Flaglister.SlotSelect

它创建了一个新的 slotselect。

将一个对象设为父对象,将一个对象设为子对象,并在构造函数中传递父引用,例如

Class SlotSelect
  Private _MainForm As MainForm
  Sub New(mf as MainForm)
    _MainForm=mf
  End Sub
...
End Class        
于 2012-06-07T02:49:59.323 回答