vb.net - 使用旧对象实例/以前的对象实例

标签 vb.net

在 Visual Basic 2008 Express 中,我想引用一个表单。但是,当我输入 Dim mainmenu as New MainMenu ,这将创建一个新实例。当我想使用表单 2 中的按钮更改表单主菜单中的标签时,我必须执行以下操作:

    Dim mainmenu As New MainMenu
    Dim pitchint As Integer
    pitchint = Val(Pitch_txt.Text) 'simple way will filter out trailing non-numerics input
    If pitchint > 720 Then
        pitchint -= 720
    ElseIf pitchint > 360 Then
        pitchint -= 360
    End If

    Pitch_txt.Text = pitchint '<--put this line here will solve your "070" issue
    mainmenu.Pitchlbl.Text = pitchint
    If Pitch_txt.Text.Length <> 0 Then
        If Pitchlbl.Text <> Pitch_txt.Text Then
            Pitchlbl.Text = Pitch_txt.Text
        End If
    End If

    Dim yawint As Integer
    yawint = Val(Yaw_txt.Text) 'simple way will filter out trailing non-numerics input
    If yawint > 90 Then
        yawint -= 90
    End If
    If yawint < -90 Then
        yawint += 90
    End If

    Yaw_txt.Text = yawint '<--put this line here will solve your "070" issue

    If Yaw_txt.Text.Length <> 0 Then
        If Yawlbl.Text <> Yaw_txt.Text Then
            Yawlbl.Text = Yaw_txt.Text
        End If
    End If

这将创建窗体主菜单的新实例。然后,当我插入行 mainmenu.Yawlbl.Text = yawintmainmenu.Pitchlbl.Text = pitchint ,没有任何 react 。我没有收到任何错误。请帮忙。提前致谢。

最佳答案

我的解决方案被错误地描述了,并且对回答这个问题的各种可能方法存在一些混淆,因此我编辑了我的原始帖子,以比较和对比本页上详细讨论的三种主要方法。

方案一:使用VB.NET默认表单实例

将此行放在 Dim mainmenu As New MainMenu 之后:

mainmenu.Show()

您可能有两个 MainMenu 窗体。这是因为 VB 允许您仅通过使用其类名来引用表单的静态实例。所以你可以说,即 MainMenu.Property = value它将对 VB 创建的静态实例进行操作。

尝试删除该行 Dim mainmenu As New MainMenu .这可能就是您需要做的所有事情(只要您 Show() 表单),因为您将引用称为与类名相同的名称。

解决方案2:遵循单例设计模式(简化版,无线程安全)

单例设计模式确保一个类只能有一个实例。将此代码放入 MainMenu 肯定会导致屏幕上出现一些错误。
Public Class MainMenu

    ' static (shared) instance of this class
    Private Shared _instance As MainMenu

    ' function which returns the static instance
    ' with lazy initialization (constructor is called once GetInstance is 
    Public Shared Function GetInstance() As MainMenu
        If _instance Is Nothing Then
            _instance = New MainMenu()
        End If
        Return _instance
    End Function

    ' private constructor to restrict instantiation of this class (only allowed in GetInstance)
    Private Sub New()
        ' This call is required by the designer.
        InitializeComponent()
        ' Add any initialization after the InitializeComponent() call.

    End Sub

    ' all the rest of your original MainMenu code here

End Class

修复错误的方法是使用一个变量来保存对 MainMenu 实例的引用。简单地,替换mainmenu带有类似 myMainMenu 的变量在你使用表格之前,把这个:
Dim myMainMenu As MainMenu = MainMenu.GetInstance()
myMainMenu.Show()

解决方案 3:创建您自己的实例

之间存在差异解决方案 1 解决方案 3 .在 解决方案 1 ,如果您只使用默认实例,您将只有一个表单实例。此解决方案允许您拥有任意数量的实例!你可能不需要这个,但是这里...

您将再次创建一个名为 myMainMenu 的 MainMenu 新实例,但这次您直接调用构造函数。
Dim myMainMenu As New MainMenu()
myMainMenu.Show()

无论您在何处通过名称调用表单 mainmenu ,将其替换为 myMainMenu .我是否提到我们将其称为 myMainMenu 而不是 mainmenu 因为我们不想使用与类名相同的名称? (VB 不区分大小写,所以 mainmenu = MainMenu ,但这很容易混淆,因为默认实例。编译器使用上下文来确定我们是在谈论类本身还是类的默认实例......)使用类名仅在您引用默认静态实例时有效,如 解决方案 1 .

此解决方案的吸引人之处在于您可以同时拥有多个 MainMenu 实例。所以你可以把它放在后面:
Dim myMainMenu2 As New MainMenu()
myMainMenu2.Show()

瞧,您打开了两个 MainMenu。但你可能不需要两个!

摘要

为什么有这么多方法?

好吧,添加第一种方法是为了吸引 VB6 程序员使用 VB.NET,因为在 VB6 中就是这样做的!准确的说,在VB6中是可以这样的,但是一些脑残的程序员还是选择了方法3。 但是默认实例方法是如此普遍,因为它对于普通程序员来说太容易使用了——尤其是所有那些外行在 VBA 中使用它!

第二种方法在某些情况下是首选,但在其他情况下不是。它是单例设计模式的简单实现。查看 Douglas Barbie 的回答中的链接,以获得对它的体面解释和一些 Java 示例。它列出了你需要使用它的所有时间的一个很好的总结——一个应该只有一次实例的记录器、一个配置加载器、一个工厂或其他实例生成器——这些可能超出了你的范围,但也许只是想想Microsoft Office 中的打印对话框。一次只需要打开一个打印窗口。这是一个很好的例子。你的代码需要这个吗?遵循该模式允许这种行为,但正如我在示例中所说的那样,还有一些额外的配置。如果应用程序足够简单,它可能不需要它。

第三个是面向对象编程的典型示例(一个很好的起点是理解 OOP;仅这些知识就可以为您提供将来解决此类问题的工具)。它使用您创建的名为 MainMenu 的类,并可能使用该类的多个实例,称为对象。这样做的一个优点是您可以拥有同一个类的两个对象实例,但这些对象具有不同值的属性。想想类 Car 的两个实例,一个有Car.Make = "Ford" ,其他 Car.Make = "Chevy" .两款车,但它们的属性(property)值(value)不同。这与前两个的不同之处仅在于您可以拥有多个实例。如果我们想要获得技术,您可以合并解决方案 1 和 3 并使用默认实例并创建您自己的实例,但几乎所有讨论它的人都警告不要这样做(谷歌“VB.NET 表单默认实例”了解更多信息那件事)。

最后,如果您正在小规模地编码某些东西,那么它对您来说是可靠的。

关于vb.net - 使用旧对象实例/以前的对象实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17680458/

相关文章:

java - 如何创建一个在用户登录后启动的桌面应用程序?

vb.net - Windows 服务启动失败

vb.net - VB.NET ArrayList到List(Of T)类型的复制/转换

vb.net - 将 `Double` 或 `Single` 转换为 `Integer` 的最简洁方法,无需舍入

vb.net - 如何保留 RichTextBox 中的文本格式,如粗体、斜体、字体颜色、字体大小等?

c# - 我在哪里可以找到 .NET 框架包装的所有 "COR_E_"HRESULT 的引用?

.net - 如何在不同的应用程序但同一个项目中访问自己的命名空间?

.net - Random.Next - 我不明白

c# - C# 和 VB.NET 之间最重要的功能区别是什么?

.net - 将 C++ printf 格式与 VB .NET 字符串格式相互转换