top
Loading...
從VisualBasic6.0到VisualBasic.NET的轉換(2)
升級
向導


將 Currency 數據類型轉換為 Decimal,因此以下代碼:

Dim x As Currency
升級后將變為:

Dim x As Decimal


Date
Visual
Basic 6.0 Date 變量在內部以 Double 格式存儲,能夠作為 Double 類型的變量操作。

Date 變量存儲為 IEEE 64 位浮點數,表示從 100 年 1 月 1 日到 9999 年 12 月 31 日的日期和從 0:00:00 到 23:59:59 的時間。任何可識別的文字日期都可以指定為 Date 變量。

當其他數字類型轉換為 Date 時,小數點左邊的值表示日期信息,而小數點右邊的值表示時間信息。午夜為 0,正午為 0.5。整個數值為負表示 1899 年 12 月 30 日之前的日期。

Visual Basic.NET


Date 在內部存儲為 64 位整數,因此無法直接作為 Double 進行操作。.NET 框架提供了 ToOADate 和 FromOADate 函數以進行 Double 和 Date 之間的轉換。將日期表示為整數形式可以簡化并加速對日期的操作。

升級
向導


升級工具并非能夠檢測到所有使用變量將 Date 存儲為 Double 的情況,但它一般會在將 Double 指定為 Date 的位置插入適當的 ToOADate 或 FromOADate 方法。例如,以下代碼:

Dim dbl As Double Dim dat As Date Dbl = dat
升級后將變為:

Dim dbl As Double Dim dat As Date Dbl = dat.ToOADate


定長字符串
Visual
Basic 6.0 除類模塊的 Public 變量之外,其他變量均可以聲明為定長字符串。

Visual Basic.NET


CLR 第一版不支持定長字符串。在后續版本中將添加這一支持功能。

升級
向導


在大多數情況下不會出現問題。假設為定長字符串表現方式,則以下代碼:

Dim MyFixedLengthString As String * 100
升級后將變為:

Dim MyFixedLengthString As New VB6.FixedLengthString(100)
有關該主題的全面說明,請參閱白皮書《準備將 Visual Basic 6.0 應用程序升級到 Visual Basic.NET》(英文)。


Type
Visual
Basic 6.0
Type 語句用于定義由用戶定義的數據類型。

Visual Basic.NET


Type 和 User-Defined Type 這兩個名稱會引起混淆,因為類、枚舉和接口也是可以由用戶定義的類型。Type 和 User-Defined Type 是從 QuickBasic 遺留下來的,在 QuickBasic 中用戶可以定義的類型只有結構和記錄。CLR 使用 Type 這一名稱廣義地包含所有數據類型。

因此,在 Visual Basic.NET 中 Type 語句將變為 Structure。

升級
向導


將 Type 語句變為 Structure,因此以下代碼:

Type MyType MyVariable As Integer End Type
升級后將變為:

Structure MyType Dim MyVariable As Short End Structure


用戶定義類型存儲
Visual
Basic 6.0 用戶定義的數據類型可以包含某種數據類型、數組或先前定義的用戶定義類型的一個或多個元素。在 Visual Basic 6.0 中,它們存儲在連續的內存塊中。

Visual Basic.NET


格式是最有效的。它可能位于一段連續的內存,也可能不。結構可以被標記為封送處理屬性,以確保能夠作為連續內存塊傳遞到 COM 組件。

升級
向導


在所有需要添加封送處理屬性的位置,API 均標記有 TODO 注釋。(屬性不是自動添加的,只有將結構傳遞到 API 時才需要它們。)


True
Visual
Basic 6.0 True 的值為 -1。

Visual Basic.NET


True 的值為 1。

鑒于語言的協同操作,需要一種適用于所有語言的一致表示法。

升級
向導


如果將布爾值強制轉換為非布爾值,代碼將標記有升級警告。例如,以下代碼:

Dim MyBoolean As BooleanDim MyInteger As Integer MyInteger = MyBoolean
升級后將變為:

Dim MyBoolean As BooleanDim MyInteger As Short ' UPGRADE_WARNING: Boolean MyBoolean is being converted into a numeric MyInteger = MyBoolean


Empty
Visual
Basic 6.0 變量均初始化為 Empty,當用于數值表達式時,變量將自動轉換為零,當用于字符串表達式時,則自動轉換為空字符串。

Visual Basic.NET


對象變量均初始化為 Nothing,當用于數值表達式時,變量將自動轉換為零,當用于字符串表達式時,將自動轉換為空字符串。使用 Nothing 代替特殊的 Empty 值可以降低語言的復雜性,語言協同操作性也更強。

升級向導

Null 和 Null 傳播
Visual
Basic 6.0 Null 值為 Variant 的子類型,表示變量不包含有效數據。Null 值通過表達式和函數“傳播”。如果表達式的任一部分為 Null,則整個表達式為 Null。將 Null 作為參數傳遞給大多數函數時,這些函數也將返回 Null。

Visual Basic.NET


不支持 Null 傳播。使用 ADO.NET 對數據進行編程的模型用于在檢索字段的值之前先檢查字段的值是否為 Null。包含 null 的變量將作為 DBNull 類型的對象封送處理至 CLR。

Visual Basic.NET 處理 Null 時更加直接:字符串函數(例如 Left())總是返回字符串,與您的預期一樣。

升級
向導


Null 值和 IsNull 函數標記有升級警告注釋。例如,以下代碼:

If x Is Null Then MsgBox "Null"
升級后將變為:

' UPGRADE_WARNING: Use of IsNull() detected If IsDBNull(x) Then MsgBox "Null"


Def<Type>
Visual
Basic 6.0 DefBool、DefByte、DefInt、DefLng、DefCur、DefSng、DefDbl、DefDec、DefDate、DefStr、DefObj 和 DefVar 語句用于在模塊級設置變量、參數和過程返回類型(以指定字符開始)的默認數據類型。

Visual Basic.NET


避免使用隱式類型聲明,提高了代碼的可讀性和可靠性。

升級
向導


將變量類型的顯式聲明插入代碼。例如,以下代碼:

DefStr a-z
Sub MySub
s = "Hello"
End Sub
升級后將變為:

Sub MySub
Dim s As String
s = "Hello"
End Sub


塊內的局部變量
Visual
Basic 6.0 從包含聲明的行至過程結束的范圍內,局部變量均可見。

Visual Basic.NET


Visual Basic.NET 支持變量的塊范圍。這意味著從包含聲明的行開始,至出現聲明的塊結束,局部變量均可見。例如:

Sub Test(x As Integer)
If x < 0 Then
Dim y As Integer = - x
'...
Else
'...
End If
End Sub
以上示例中的變量 y 僅在聲明該變量的塊中可用;更確切地說,它僅在其聲明至 Else 語句之間可用。如果需要在整個過程中使用變量,則必須在 If/Else/End If 控制結構之外聲明該變量。

變量的塊范圍是許多結構語言共有的功能。過程局部變量允許定義過程內部變量,從而對結構化編程提供支持,與此類似,塊級別變量允許定義代碼塊內部變量,從而對結構化分解提供支持。

升級
向導


如果變量在塊內聲明,變量將自動移至模塊級范圍。例如,以下代碼:

If x =1 Then
Dim y As Integer
End If
升級后將變為:

Dim y As Integer
If x =1 Then
End If


新的自動重新實例化
Visual
Basic 6.0 窗體的類變量聲明 Dim x As New <classname> 將導致編譯器每次引用 x 時生成代碼。此代碼檢查 x 是否為 Nothing;如果是 Nothing,則創建類的新實例。例如,以下代碼:

Dim x As New MyClass
'...
Call x.MyMethod()
等同于:

Dim x As MyClass
'...
If x Is Nothing Then
Set x = New MyClass
End If
Call x.MyMethod()
即使變量已經設置為 Nothing,在下一次調用時該變量仍將重新實例化。

Visual Basic.NET


窗體的變量聲明 Dim x As New <classname> 等同于 Dim x As <classname> = New <classname>。引用通過此語法聲明的變量不會生成特殊代碼。

Visual Basic.NET 聲明 As New 比 Visual Basic 6.0 中的同一聲明更加有效。大多數對這類變量的引用不需要額外的開銷。而且,Visual Basic 6.0 的“自動實例化”行為對于發現它的許多編程人員來說非常古怪。

升級
向導


這極少會成為問題。但是,如果代碼嘗試使用已設置為 Nothing 的類,將導致運行時異常。該異常很容易檢測到。然后,可以方便地修改代碼以實例化類的新版本,如下例所示:

Dim x As New MyClass
x = Nothing
x = New MyClass


對象終結
Visual
Basic 6.0 COM 引用計數機制用于垃圾回收對象實例。如果對象不在循環中,當對象不再使用,引用計數會立即檢測到此情況,并且運行終結代碼。

Visual Basic.NET


跟蹤垃圾回收器從存儲在堆棧變量、模塊變量和共享變量中的可及引用開始,將對象過一遍。此跟蹤進程作為后臺任務運行,因此在指向對象的最后一個引用結束和添加新引用之間有一個不定的時間段。

在某些情況下,客戶端確實需要能夠強制某一對象釋放資源。CLR 規定這樣的對象應當實現 IDisposable 接口,這就提供了 Dispose 方法。當客戶端結束對具有 Dispose 方法的對象的使用時,它可以顯式調用 Dispose 方法以釋放其資源。例如,包裝數據庫連接的對象應當公開 Dispose 方法。

跟蹤垃圾回收器能夠正確釋放引用循環中的對象。此外,跟蹤垃圾回收器的性能比引用計數要好得多。

升級
向導


在大多數情況下,這一改變不會導致問題。如果您的代碼中使用了資源句柄開放(連接或文件句柄),則必須顯式關閉此句柄。此問題易于檢測并會導致運行時錯誤。


數組
Visual
Basic 6.0 數組可以由任何整數數字的上下限限定。如果在聲明中未指定下限,將使用 Option Base 語句確定默認下限。

Visual Basic.NET


為了與其他語言協同操作,所有數組的下限均必須為零。這樣就不再需要 Option Base 語句。

升級
向導

ReDim
Visual
Basic 6.0 Visual Basic 6.0 中的固定大小數組和不定大小數組有所區別。固定大小數組通過 Dim 語句聲明,在此語句包括此聲明中的數組界限。動態數組在 Dim 語句中聲明,不指定界限信息。在使用動態數組之前,需要通過 ReDim 語句重新標注動態數組。在 Visual Basic 6.0 中,ReDim 語句提供了在單個語句中為動態數組聲明和分配空間的快捷方法。ReDim 語句是 Visual Basic 6.0 中唯一能夠同時聲明和初始化變量的語句。

Visual Basic.NET


ReDim 語句僅用于為數組分配或重新分配空間,而不能用于重新分配數組。這是因為 Visual Basic.NET 中的所有數組均是動態的,在 Visual Basic.NET 中 Dim 語句既可用于聲明動態數組,又可用于初始化動態數組。

由于所有變量聲明均可聲明變量并指定變量的初始值,使用 ReDim 同時聲明和初始化變量就變得多余和不必要了。只需要 Dim 語句聲明變量使語言更加簡單、一致性更高。

升級
向導


如果 ReDim() 用于聲明數組,在代碼中會自動插入相應的聲明。但是,最好的方法是您自己先在數組中插入 Dim 語句,因為使用 ReDim 聲明數組需要升級工具來推斷正確的聲明。使用 ReDim 也產生了不便處理的代碼,因為數組在兩處進行了同一聲明。


賦值
Visual
Basic 6.0 賦值形式有兩種:Let 賦值(默認)和 Set 賦值。用 Set 語句為 cn 賦值。


Visual Basic.NET


僅有一種賦值形式。x = y 意味著將變量或屬性 y 的值賦給變量或屬性 x。對象類型變量的值是對對象實例的引用,因此如果 x 和 y 是引用類型的變量,將執行引用賦值。這種單一形式的賦值減少了語言的復雜性,并使代碼可讀性更強。

升級向導


刪除 Set 和 Let 語句。解析強類型對象的默認屬性,并將屬性顯式添加到代碼中。

有關該主題的全面說明,請參閱白皮書《準備將 Visual Basic 6.0 應用程序升級到 Visual Basic.NET》(英文)。


And、Or、Xor 和 Not
Visual
Basic 6.0 And、Or、Xor 和 Not 運算符可以執行邏輯運算或位運算(取決于表達式)。

Visual Basic.NET


And、Or 和 Xor 僅適用于布爾型。對于 And 和 Or 運算符,如果第一個運算數的值足以確定運算符的結果,則運算符將簡化計算。新的運算符 BitOr、BitAnd 和 BitXor 均用于位邏輯運算。Bitxxx 運算符不具有簡化作用。

升級
向導


如果 And/Or 語句是非布爾型或者包含函數、方法或屬性,此語句將升級為使用兼容性函數,與 Visual Basic 6.0 中的表現形式相同。如果 And/Or 語句是布爾型,此語句將升級為使用本地 Visual Basic.Net 語句。

有關該主題的全面說明,請參閱白皮書《準備將 Visual Basic 6.0 應用程序升級到 Visual Basic.NET》(英文)。


運算符優先級
Visual
Basic 6.0 邏輯和位的 And、Or、Xor 和 Not 運算符的優先級高于比較運算符。

Visual Basic.NET


And、Or、Xor 和 Not 運算符的優先級低于比較運算符,因此 a > b And a < c 將被認為是 (a > b) And (a < c)。新的 BitAnd、BitOr 和 BitXor 運算符的優先級高于比較運算符,因此 a BitAnd &HFFFF <> 0 將被認為是 ((a BitAnd &HFFFF) <> 0)。

由于 BitAnd、BitOr 和 BitNot 運算符可以返回數值結果,因此其優先級高于關系運算符,這樣,就允許這三個運算符返回的結果與其他值進行比較。

升級
向導


由升級向導處理。有關該主題的全面說明,請參閱白皮書《準備將 Visual Basic 6.0 應用程序升級到 Visual Basic.NET》(英文)。


調用過程
Visual
Basic 6.0 支持兩種類型的過程調用:一種使用 Call 語句,要求使用括號括住參數列表;另一種不使用 Call 語句,不能使用括號來括住參數列表。

在 Visual Basic 6.0 中的一種常見情況是,開發者調用的過程不使用關鍵字,而又在參數列表外使用括號。幸運的是,當有一個以上的參數時,編譯器會將其作為語法錯誤檢測出來。但是,當僅有一個參數時,單一參數外的括號會將參數變量傳遞為 ByVal 而不是 ByRef。這會導致難以找到的小錯誤。

Visual Basic.NET


在所有情況下參數列表均需要使用括號。

升級向導


為沒有使用括號的過程調用插入括號。


靜態過程
Visual
Basic 6.0 通過 Static 關鍵字可以聲明過程,此關鍵字表明在調用之間保留過程的局部變量。

Visual Basic.NET


在過程中不支持 Static 關鍵字,并且所有的靜態局部變量均需通過 Static 語句顯式聲明。

需要將過程中的所有變量均聲明為靜態的情況很少。刪除此功能簡化了語言,并且提高了可讀性,因為局部變量總是位于堆棧中,除非已顯式聲明為 Static。

升級
向導


如果過程標記為 Static,則所有的局部變量均變為 Static。


參數的 ByVal/ByRef 默認值
Visual
Basic 6.0 參數未指定其默認值為 ByVal 或 ByRef 時,其默認值為 ByRef。

Visual Basic.NET


<參數未指定其默認值為 ByVal 或 ByRef 時,其默認值為 ByVal。

將參數默認值指定為 ByVal 而不指定為 ByRef,可以避免過程錯誤地修改由調用方傳遞的變量。這也使得默認的調用規則與賦值一致,以便參數有效地綁定至表達式(通過表達式賦值為正式參數)。

請用戶注意避免由 Visual Basic 6.0 升級到 Visual Basic.NET 帶來的混亂。如果用戶輸入的參數聲明未顯式指定其默認值為 ByVal 或 ByRef,IDE 將為其自動添加 ByVal 關鍵字。

升級
向導


為沒有指定 ByVal 或 ByRef 為默認值的參數添加 ByRef。


IsMissing 參數和可選參數
Visual
Basic 6.0 沒有默認值的可選 Variant 參數將被初始化為特殊的錯誤代碼,此錯誤代碼可以由 IsMissing 函數檢測出來。

Visual Basic.NET


在 Visual Basic.NET 中要求所有的可選參數均指定默認值。這樣可以減少語言中特殊值的數量,從而簡化語言。

升級
向導


IsMissing 函數由 IsNothing 函數代替,并且標記有升級警告注釋。


ParamArray 參數
Visual
Basic 6.0 當變量傳遞給 ParamArray 參數時,可以通過被調用的函數修改。不支持 ByVal ParamArray 元素。

Visual Basic.NET


當變量傳遞給 ParamArray 參數時,不能通過被調用的函數修改。不支持 ByRef ParamArray 元素。

ParamArray 參數最常見的情況是不修改傳遞給此參數的變量。不支持 ByRef ParamArray 參數簡化了 ParamArray 調用規則,因為 ParamArray 參數將被指定為正常數組。這樣,ParamArray 參數可以擴展到任何元素類型,同時需要 ParamArray 參數的函數均可通過數組(而不是參數列表)直接調用。

北斗有巢氏 有巢氏北斗