2012-11-26 36 views
10

Tôi có một cái gì đó như thế này:VB.NET boolean không nhận được giá trị mặc định của nó trong vòng lặp?

For i = 1 To 4 
     Dim x As Boolean 
     If i < 3 Then x = True 
     Console.WriteLine(x) 
Next 

Cung cấp cho tôi: Đúng Đúng Đúng Đúng

và điều này

For i = 1 To 4 
     Dim x As Boolean = False 
     If i < 3 Then x = True 
     Console.WriteLine(x) 
Next 

Cung cấp cho tôi: Đúng Đúng False False

Cả hai đều không cho tôi kết quả thứ hai? The MSDN article nói rằng Giá trị mặc định của Boolean là Sai.

Có phải là lỗi hoặc tôi thiếu gì đó không?

Trả lời

13

Cảm ơn bạn cho câu hỏi rất thú vị. Tôi mất mã mẫu:

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 

Và đã xem xét các IL tạo ra thông qua 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 

Điều này cho chúng ta biết là mặc dù bạn đang khai báo x trong vòng lặp (Dim x as Boolean) và (Dim x as boolean = False), khai báo thực tế của biến xảy ra bên ngoài vòng lặp.

Bởi vì bạn đặt biến của mình một giá trị mặc định bên trong vòng lặp trong Test2, nó thực sự đặt giá trị thành False ở đầu mỗi lần lặp. Bởi vì bạn không gán giá trị cho x trong vòng lặp Test1 và nó chỉ được khai báo sau khi ngoài vòng lặp, nó giữ lại giá trị nó có trong lần lặp trước đó.

4

Biến x không được khởi tạo trên mỗi lần lặp của vòng lặp - chỉ lần đầu tiên. Ví dụ 1 là giống như

Dim x As Boolean 
For i = 1 To 4 
     If i < 3 Then x = True 
     Console.WriteLine(x) 
Next 

Khi bạn nhìn thấy nó theo cách này nó có ý nghĩa tại sao bạn kết thúc với Đúng Đúng Đúng Đúng bởi vì bạn đang thiết lập nó là True trên đèo đầu tiên thông qua các vòng lặp và không có gì là bao giờ đặt nó thành Sai.

Ví dụ 2 cũng giống như

Dim x As Boolean 
For i = 1 To 4 
     x = False 
     If i < 3 Then x = True 
     Console.WriteLine(x) 
Next 

Chắc chắn không phải là trực quan, nhưng đó là những gì các trình biên dịch đang làm

+0

Điều này là chính xác, tôi đã đăng IL đã tạo trong câu trả lời ở trên xác nhận xác nhận của bạn. –

Các vấn đề liên quan