2015-09-16 21 views
6

以下のコードサンプルでは、​​変数currOnがループの外側に持ち上げられ、一度しかインスタンス化されないようです。たとえば、itemListに3つのアイテムがあり、2回目の繰り返しでSomeFunctionThatDoesSomeStufftrueを返すとします。 currOnの値はtrueになります。 3回目の反復では、与えられたVB.NETがブロックスコープ言語で、currOnは再インスタンス化され、デフォルトはfalseになると思っていました。しかし、それはtrueのままであり、従ってsOnの値に関係なく、それ以上の反復で更新されないことがわかります。それはcurrOnの宣言がループの外側にプルアップされるjavascriptの関数スコープのようです。誰がここで何が起こっているのか知っていますか?さらなる例としてVB.NETのループ関数のスコープとブロックのスコープ

 For Each item As MyItem In itemList 
      Dim currOn As Boolean 
      Dim sOn As Boolean = SomeFunctionThatDoesStuff(item) 
      currOn = currOn OrElse sOn 

      Debug.Print(String.Format("the value of currOn is: {0}", currOn)) 
     Next 

、明示的currOn = falseすべての反復を設定すると、私は上記の仕事に期待した通りに動作するようです。

  For Each item As MyItem In itemList 

       Dim currOn As Boolean = False 
       Dim sOn As Boolean = SomeFunctionThatDoesStuff() 
       currOn = currOn OrElse sOn 

       Debug.Print(String.Format("the value of currOn is: {0}", currOn)) 
      Next 
+1

非常に興味深い、あなたはループの外にコードを取り、ちょうどそれを手動で繰り返される場合は、同じスコープ内の変数の宣言を複製するため、コンパイルエラーになるだろうので、 - ただ一つの行があるという事実は、コンパイラが一度それを読んで、プロセスが複製されるという事実にかかわらず、それを「合法」コードとしてフラグを立てることを意味しなければならない。 –

+0

これも私を驚かせる。おそらくこれはVB6コードのポートをより良くするためです。 – GSerg

+0

興味深い...たぶんVB.NETのオプションとは何か? 2つのコードサンプルはまったく同じではないことに注意してください - 2つ目のコードサンプルは内部ループを持っています。最初の例の各ループの始めに 'currOn'を" False "に初期化すると、動作を知りたいのです。 – Tim

答えて

5

あなたはブロックスコープ内で宣言されているForループ内で変数を宣言します。ブロック内で宣言されたオブジェクトは、そのブロック内でのみアクセス可能ですが、プロシージャ全体で有効です。 MSDNから

変数の範囲はブロックに制限されても、その寿命は、依然として全体の手順のことです。プロシージャ中にブロックを複数回入力すると、各ブロック変数は以前の値を保持します。このような場合に予期しない結果が発生するのを避けるために、ブロックの先頭でブロック変数を初期化することをお勧めします。

MSDNのリンク:https://msdn.microsoft.com/en-us/library/1t0wsc67.aspx