VB.net中的公共子New()触发函数

本文关键字:函数 New net VB | 更新日期: 2023-09-27 18:04:03

嘿,我正在转换一些c#代码到VB.net,并注意到c#代码有一个Public Sub New()。c#代码如下:

private readonly SController _controller; 
public SView():this(new SController()) { }
public SView(SController controller)
{
    InitializeComponent();
    _controller = controller;
    controller.EnumerateDevices(deviceDropdown.Items);
    _thread = new Thread(ReadLoop) {IsBackground = true};
    _thread.Start();
}

并将上述内容转换为VB.net:

Private ReadOnly _controller As SController
Public Sub New()
   Me.New(New SController())
End Sub
Public Sub New(controller As SController)
   InitializeComponent()
   _controller = controller
   controller.EnumerateDevices(deviceDropdown.Items)
   _thread = New Thread(AddressOf ReadLoop) With { _
      .IsBackground = True _
   }
   _thread.Start()
End Sub

我遇到的问题是,因为VB开始于:

Private Sub SView_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

我如何告诉它启动Public Sub New()函数?

我试着写:

Private Sub SView_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    Me.New(New SController())
End Sub

但是它给我的错误是:

Constructor call is valid only as the first statement in an instance constructor.

任何帮助将是伟大的解决这个问题!

Private Sub SView_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
   Dim _sView As New SView
End Sub

当我在Dim _sView As New SView

VB.net中的公共子New()触发函数

我如何告诉它启动Public Sub New()函数?

你不能。Sub New()是类的构造函数,执行它是为了初始化类的实例。

默认构造函数(没有任何参数的构造函数)在表单实例化时和Load事件触发之前被调用。如果您想验证这一点,请在构造函数中放置一个断点并调试您的解决方案。

Sub New在创建新实例时被调用。
"子"= = =>"昏暗的foo FooBar"得到它?

一些混淆可能是因为你的SView构造函数是重载的:

' simple constructor
Public Sub New()
   Me.New(New SController())       ' calls overload below
End Sub
Public Sub New(controller As SController)
   InitializeComponent()           ' this is apparently a form????
   _controller = controller
   controller.EnumerateDevices(deviceDropdown.Items)
   _thread = New Thread(AddressOf ReadLoop) With { _
      .IsBackground = True }
   _thread.Start()
End Sub

它可以带或不带对控制器的引用来调用:

Dim _sView As New SView
' or
Dim _ctrlr As New SController
Dim _sView As New SView(_ctrlr)

在第一种情况下,你的SView将创建它自己的新控制器。在第二种情况下,它将使用在构造函数调用(New SView(_ctrlr))中传递给它的那个。在两个情况下,你的新对象有一个控制器对象。

如果一个新的类对象不应该在没有参数的情况下存在,只需删除简单(空)构造函数,这样就会抛出异常:

Dim emp As New Employee(empName)
' this one fails if you remove the "Sub New()":
Dim emp As New Employee()

如果你只想用你创建的控制器创建新的实例,只需删除简单的/空构造函数。

编辑

It never hits the Load when I put a break on line [Dim _sView As New SView]

加载表单与创建表单实例不同。窗体只是类,Load事件在第一次使用对象上调用Show方法时被调用。这是一个很好的的东西,因为它允许我们创建一个表单实例,并在显示之前使用它。长标记:

Dim _sView As SView          ' simple DECLARES the object name and type
_sView = New SView           ' create instance (exec [Sub new])
_sView.FormSetup             ' do some first time only stuff
_sView.Show                  ' show the form (fires [Load] event)

FormSetup可能是我写的一个方法,它是一些任务只在第一次使用时完成。如果我随后只是Hide表单,我可以跳过所有这些,而不是在Load事件中使用它。然而,注释解释了每一行的内容。

如果你想在构造函数中调用一个已经构造的实例中的逻辑,你需要重构以将该逻辑移出构造函数:

Private ReadOnly _controller As SController
Public Sub New()
   Me.New(New SController())
End Sub
Public Sub New(controller As SController)
   Initialize(controller)
End Sub
Private Sub Initialize(controller As SController)
   InitializeComponent()
   _controller = controller
   controller.EnumerateDevices(deviceDropdown.Items)
   _thread = New Thread(AddressOf ReadLoop) With { _
      .IsBackground = True _
   }
   _thread.Start()
End Sub

然后不调用Me.New(New SController())而是调用Me.Initialize(New SController())