Danke für die sehr interessante Frage. Ich nahm den Beispielcode:
Module Module1
Sub Main()
Test1()
Test2()
Console.ReadKey()
End Sub
Public Sub Test1()
For i = 1 To 4
Dim x As Boolean
If i < 3 Then x = True
Console.WriteLine(x)
Next
End Sub
Public Sub Test2()
For i = 1 To 4
Dim x As Boolean = False
If i < 3 Then x = True
Console.WriteLine(x)
Next
End Sub
End Module
Und warf einen Blick auf die erzeugte IL über ILSpy:
Test1()
.method public static
void Test1() cil managed
{
// Method begins at RVA 0x2120
// Code size 33 (0x21)
.maxstack 2
.locals init (
[0] int32 i,
[1] bool x,
[2] bool VB$CG$t_bool$S0,
[3] int32 VB$CG$t_i4$S0
)
IL_0000: nop
IL_0001: ldc.i4.1
IL_0002: stloc.0 // put 1 on top of stack
// loop start (head: IL_0003)
IL_0003: ldloc.0 // load i on top of stack
IL_0004: ldc.i4.3 // load 3 on top of stack
IL_0005: clt // compare if 0 is less than 3
IL_0007: stloc.2
IL_0008: ldloc.2
IL_0009: brfalse.s IL_000d // if i >= 3, jump to IL_000d
IL_000b: ldc.i4.1 // load true onto stack
IL_000c: stloc.1 // set x = true
IL_000d: ldloc.1 // load x onto stack
IL_000e: call void [mscorlib]System.Console::WriteLine(bool) // print x
IL_0013: nop
IL_0014: nop
IL_0015: ldloc.0 // load i onto stack
IL_0016: ldc.i4.1 // load 1 onto stack
IL_0017: add.ovf // add i + 1
IL_0018: stloc.0 // set i = i + 1
IL_0019: ldloc.0 // load i
IL_001a: ldc.i4.4 // load 4
IL_001b: stloc.3 // store 4 in iterator variable
IL_001c: ldloc.3 // load 4 from iterator variable
IL_001d: ble.s IL_0003 // if i <= 4, go to beginning of loop
// end loop
IL_001f: nop
IL_0020: ret
} // end of method Module1::Test1
Test2()
.method public static
void Test2() cil managed
{
// Method begins at RVA 0x2150
// Code size 35 (0x23)
.maxstack 2
.locals init (
[0] int32 i,
[1] bool x,
[2] bool VB$CG$t_bool$S0,
[3] int32 VB$CG$t_i4$S0
)
IL_0000: nop
IL_0001: ldc.i4.1 // load 1 onto stack
IL_0002: stloc.0 // set i = 1
// loop start (head: IL_0003)
IL_0003: ldc.i4.0 // load 0 onto stack
IL_0004: stloc.1 // set x = false
IL_0005: ldloc.0 // load i onto stack
IL_0006: ldc.i4.3 // load 3 onto stack
IL_0007: clt // compare i to 3
IL_0009: stloc.2 // store result in iterator variable
IL_000a: ldloc.2 // load iterator variable
IL_000b: brfalse.s IL_000f // if i >= 3, jump to IL_00f
IL_000d: ldc.i4.1 // load 1 onto stack
IL_000e: stloc.1 // set x = true
IL_000f: ldloc.1 // load x onto stack
IL_0010: call void [mscorlib]System.Console::WriteLine(bool) // print x
IL_0015: nop
IL_0016: nop
IL_0017: ldloc.0 // load i onto stack
IL_0018: ldc.i4.1 // load 1 onto stack
IL_0019: add.ovf // add i + 1
IL_001a: stloc.0 // set i = i + 1
IL_001b: ldloc.0 // load i onto stack
IL_001c: ldc.i4.4 // load 4 onto stack
IL_001d: stloc.3 // store 4 into iterator variable
IL_001e: ldloc.3 // load 4 from iterator variable
IL_001f: ble.s IL_0003 // if i <= 4, go to beginning of loop
// end loop
IL_0021: nop
IL_0022: ret
} // end of method Module1::Test2
Was sagt uns das? ist, dass, obwohl Sie x in der Schleife deklarieren (Dim x as Boolean
) und (Dim x as boolean = False
), die eigentliche Deklaration der Variablen außerhalb der Schleife passiert.
Da Sie Ihrer Variablen innerhalb der Schleife in Test2
einen Standardwert geben, setzt sie den Wert zu Beginn jeder Iteration auf False
. Da Sie in der Schleife Test1
keinen Wert an x zuweisen und nur einmal außerhalb der Schleife deklariert wird, behält es den Wert, den es in der vorherigen Iteration hatte.
Das ist korrekt, ich habe die generierte IL in meiner obigen Antwort gepostet, die Ihre Behauptung bestätigt. –