2009年11月10日 星期二

VB.Net 區塊變數的陷阱

今天在幫同事Debug時,發現了一個之前自己也沒注意到的觀念上的錯誤
請大家先看以下程式片段:
   1: Module Module1
   2:     Sub Main()
   3:         For i As Integer = 0 To 1
   4:             Dim n As Integer
   5:             n += 1
   6:             Console.WriteLine(n)
   7:         Next
   8:         Console.ReadLine()
   9:     End Sub
  10: End Module

上面程式結果,大家看印出來的2次n的值分別是多少?我想很多人應該都跟我一樣認為是2個1吧,實際上run了才發現,只有第一次是1,第2次的值變成2了.

怎會這樣?n的值不是每次宣告時就變成初始值嗎?所以應該是2個0才對啊,仔細查了一下MSDN,發現有以下這句話:

即使變數的範圍限制在一個區塊內,其存留期 (Lifetime) 仍然是整個程序的存留期。如果您在程序執行期間進入該區塊多次,每個區塊變數會保留其之前的值。如果要避免在這種情況下產生無法預期的結果,最好在區塊開頭即初始化區塊變數.

原來之前一直以為,block variable在Next後遇到Dim應該會重新給初始值,但是因為Dim本身並非指定陳述式(Assignment Statement),在n的值已經存在的情況下,Dim就不會去做變數初始化的動作,但如果你宣告時有寫Dim n As Integer=0時,此時就會變成指定陳述式,每次遇到這行就一定會設為0了.
搞懂這個觀念後再來看以下的範例:


   1: Module Module1
   2:     Sub Main()
   3:         For J As Integer = 1 To 2
   4:             For I As Integer = 1 To 3
   5:                 Dim N As LongN = N + 1
   6:                 Console.WriteLine(N)
   7:             Next
   8:         Next
   9:         Console.ReadLine()
  10:     End Sub
  11: End Module

這次印出來的N應該是多少?是111111,123123,還是123456?如果你有看懂上面的觀念,應該會猜的出來答案是123456了吧,記住,即使是區塊變數,生命週期是存留在整個程序之中的.

總之,宣告變數時最好還是不要偷懶手動給初始值,不要太依賴資料型態的初始值,以免發生錯誤.

沒有留言:

張貼留言