6

デフォルト設定の新しいWinForms.NET4.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}は、デフォルトのインスタンスを介してそれ自体を参照することはできません。代わりに「Me」を使用してください。

同じ行でこの警告も表示されます。

インスタンスを介した共有メンバー、定数メンバー、列挙型メンバー、またはネストされた型へのアクセス。修飾式は評価されません。

デフォルトのインスタンスがここで意味されていると仮定すると、それは無限ループになります-VSはに変更Me.AAA()してからForm1.AAA()元に戻すことを提案します。AAA()両方で動作します。

に変換Private Sub AAA()するとShared、エラーが解決します。Microsoftの観点からは、少なくとも1つが共有されている場合は、すべてのオーバーロードを共有する必要があるようです。または、このデフォルトのインスタンスの混乱が発生します。なんで?

明確にするために、ここではデフォルトインスタンスを使用せず、共有呼び出しを実行します。

誰かが同じ状況に遭遇した場合は、アドバイスしてください。

4

4 に答える 4

4

Formクラスのタイプと同じ名前の変数エイリアスを作成することは、間違いなく最も悲惨なVB.NETの問題です。しかし、VB6開発者にVB.NETに移行するための戦いのチャンスを与える必要がありました。

回避策は、呼び出すメソッドについて明示的にしようとするのをやめることです。これは正常にコンパイルされ、少なくともスニペットでは明確です。

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

それが本当に痛い場合は、2つのメソッドを交換するだけで、あいまいさがなくなります。

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()オープニングコードのように)呼び出すのに「問題ありません」。電話。ただし、共有呼び出しで始まり、最終的にインスタンスデータにアクセスする他のコードパスは、パスがどれほど厄介であっても、ループしてクラッシュします。Form1Form1

参照: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 に答える