6

考虑以下代码,在一个全新的 WinForms .NET 4.0 应用程序中,使用默认设置:

Public Class Form1
  Private Sub AAA()
    Form1.AAA(Nothing) 'cannot refer to itself through its default instance; use 'Me' instead.
  End Sub

  Private Shared Sub AAA(str As String)
  End Sub
End Class

我收到此错误:

{FORM_CLASS_NAME} 不能通过其默认实例引用自己;改用“我”。

我也在同一行收到此警告:

通过实例访问共享成员、常量成员、枚举成员或嵌套类型;将不评估限定表达式。

假设这里是默认实例,它会以无限循环结束 - VS 建议更改Me.AAA()Form1.AAA(),然后返回。AAA()两者都适用。

转换Private Sub AAA()Shared解决错误。从微软的角度来看,所有的重载都必须共享,如果至少有一个是的话。或者你得到这个默认实例混淆。为什么?

为了澄清,我不想在这里使用默认实例,只是做一个共享调用。

如果有人遇到同样的情况,请指教。

4

4 回答 4

4

创建一个与 Form 类的类型同名的变量别名无疑是 VB.NET 中最严重的一个问题。但是有必要给 VB6 开发人员一个转向 VB.NET 的战斗机会。

解决方法是停止尝试明确说明您要调用的方法。这编译得很好并且是明确的,至少在你的代码片段中:

  Private Sub AAA()
       AAA(Nothing)       '' fine
  End Sub

如果那真的很痛,那么只需交换这两种方法即可消除歧义:

Private Shared Sub AAA(str As String)
End Sub

Private Sub AAA()
    Form1.AAA(Nothing)    '' fine
End Sub
于 2013-03-12T20:29:46.050 回答
2

你能摆脱这个吗?您的用法将Form1.AAA()与. 非常相似code.AAA()

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        code.AAA()
    End Sub

    Private Class code
        Public Shared Sub AAA()
        End Sub
    End Class

End Class
于 2013-03-12T14:53:23.517 回答
1

编辑

鉴于 OP 中的新信息 - 您的问题的另一个解决方案可能是使用可选参数 - 即:

Private Shared Sub AAA(Optional ByVal str As String = Nothing)

此外 - 如果您只是更改声明的顺序,则解决方案以“正确”的方式进行 - 这避免了编译器错误:

Private Shared Sub AAA(ByVal str As String)
End Sub

Private Sub AAA()
    Form1.AAA(Nothing)
End Sub

--

将其保留在下方,因为它在其他情况下可能会有所帮助

也许您的大型应用程序做了这样的事情 - VB 充满了这样的混乱,您可以让自己陷入其中。这将编译但会崩溃:

Public Class Form1

    Private Shared Sub AAA()
        Form1.Text = "this"
    End Sub

    Private Sub Label1_TextChanged(sender As System.Object,  _
                                             e As System.EventArgs) _
                                             Handles Label1.TextChanged
        Form1.AAA()
    End Sub

End Class

同样,这实际上是“好的”(我用这个词很松散)......

Public Class Form1
    Private Shared dont As Boolean = True

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) _
                                                      Handles MyBase.Load
        dont = False
    End Sub

    Private Shared Sub AAA()
        If Not dont Then Form1.Text = "this"
    End Sub

    Private Sub Label1_TextChanged(sender As System.Object, _
                                               e As System.EventArgs) _
                                               Handles Label1.TextChanged
        Form1.AAA()
    End Sub

End Class

这是因为文本更改处理程序将在 Form1 完成加载之前触发(即:期间InitializeComponent()!)并将引用尚未完成创建的默认实例 - 因此 VB 尝试为您创建一个新实例,以便您可以调用共享方法使您陷入无限循环。

奇怪的是,Load处理程序“很好”(再次,松散地)调用Form1.AAA()- 就像在您的开始代码中一样 - 因为默认实例(类Form1的实例Form1)此时已完成创建,并且不会创建另一个以满足称呼。然而,任何其他代码路径,从共享调用开始并最终触及任何实例数据,无论路径多么曲折,都会循环并崩溃。

另请参阅:为什么在 VB.Net 中每个表单都有一个默认实例,但在 C# 中却没有?

于 2013-03-12T17:08:32.880 回答
0

不清楚您要整体完成什么。在 OP Form1.AAA 中应该只是 AAA。

Private Sub AAA()
    AAA(Nothing)
End Sub
Private Sub AAA(str As String)
    If str IsNot Nothing Then MsgBox(str) ' else ???
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    AAA()
    AAA("hello")
End Sub
于 2013-03-12T21:25:11.010 回答