3

以下のコードをご覧ください。

Public Class TestClass
    Public TestProperty As Integer
End Class

Public Class Form1

    Private Sub Form1_Load(ByVal sender As Object, 
                           ByVal e As System.EventArgs) Handles Me.Load
        Dim i As Integer
        Dim j As Integer
        For j = 0 To 2
            For i = 0 To 10
                Dim k As Integer
                Dim tc As TestClass
                tc = New TestClass
                tc.TestProperty = tc.TestProperty + 1
                k = k + 1
            Next
        Next
    End Sub
End Class

tcFOR ループの反復ごとに新しいオブジェクト ( と呼ばれる) が作成されるためtc.TestProperty、常に1. これが変数の場合に当てはまらないのはなぜkですかk。これはおそらく値型と参照型の扱い方に関係していると思いますが、確認したかったのです。

4

4 に答える 4

1

これは、何かがブロック レベルとして定義されると、ループに関係なくブロック レベル全体に適用されるためです。通常、IF ブロック ステートメントのような制御ロジックを使用すると、スコープが開始および終了し、コード行が繰り返されません。

ループ構造内では、Dim ステートメントが複数回呼び出されているように見えても、変数はそのブロック内で定義されています。実際には実行可能なステートメントではありません (上記の 1 つのコメントで述べたプレースホルダーの定義と予約にすぎません)。

「tc」と同じように動作させるには、同様の方法で初期化する必要があります。(定義ではなく、ループごとに 0 への代入が発生します)

Dim k As Integer = 0

代わりに、tc の処理方法を変更すると、ループ内でずっとブロック スコープ内にある k と同じように動作します。以下の例では、tc もループごとに再定義されていません。

Dim tc as TestClass
if tc is nothing then tc = New TestClass
于 2013-02-15T01:59:39.120 に答える
0

この質問のタイトルが示すように、変数の存続期間に対してスコープをクエリしています。

ローカル変数のスコープでありktc内部Forループです。寿命はの全体ですSub

を調整した場合tc = New TestClassIf tc Is Nothing Then tc = New TestClassおよび原因となる警告を無視した場合)、tc.TestProperty増分も表示されるはずです。

于 2012-07-31T07:24:47.190 に答える
0

「Dim k As Integer」は、実際には「スペース予約」以外のコードには変換されません (これはコンパイル時に確実に行われます)。したがって、アプリケーションはその文を 10 回渡しません。

証拠として、そのコード行にトレースブレットを配置することはできません!

一方、コードはループごとに新しいオブジェクト TestClass (真新しい変数 "TestProperty を保持) を作成し、それを変数 "tc" に割り当てます。以前のオブジェクトはすぐに失われ、炭水化物が収集されます。

于 2012-07-31T07:37:36.267 に答える
0

Dim k As Integer = 01のままにしておく必要があります。

これは、それを「宣言して初期化」している間、Dim k As Integer その値を保持するためです。Dim k As Integer = 0

具体的には、「値を変更してから Dim ステートメントに戻ると、変更された値は Dim ステートメントで指定された値に置き換えられます。」

実際、なぜ範囲外に出ないように見えるのかわかりません。Newキーワードがなければ、同じメモリブロックを使用している可能性があります。

于 2012-07-30T06:43:56.377 に答える