从VB 6.0到VB.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

  1<type>   
  2Visual   
  3Basic 6.0 DefBool、DefByte、DefInt、DefLng、DefCur、DefSng、DefDbl、DefDec、DefDate、DefStr、DefObj 和 DefVar 语句用于在模块级设置变量、参数和过程返回类型(以指定字符开始)的默认数据类型。   
  4  
  5  
  6  
  7Visual Basic.NET   
  8  
  9  
 10避免使用隐式类型声明,提高了代码的可读性和可靠性。   
 11  
 12  
 13  
 14升级   
 15向导   
 16  
 17  
 18将变量类型的显式声明插入代码。例如,以下代码:   
 19  
 20DefStr a-z   
 21Sub MySub   
 22s = "Hello"   
 23End Sub   
 24升级后将变为:   
 25  
 26Sub MySub   
 27Dim s As String   
 28s = "Hello"   
 29End Sub   
 30  
 31  
 32块内的局部变量   
 33Visual   
 34Basic 6.0 从包含声明的行至过程结束的范围内,局部变量均可见。   
 35  
 36  
 37  
 38Visual Basic.NET   
 39  
 40  
 41Visual Basic.NET 支持变量的块范围。这意味着从包含声明的行开始,至出现声明的块结束,局部变量均可见。例如:   
 42  
 43Sub Test(x As Integer)   
 44If x &lt; 0 Then   
 45Dim y As Integer = - x   
 46'...   
 47Else   
 48'...   
 49End If   
 50End Sub   
 51以上示例中的变量 y 仅在声明该变量的块中可用;更确切地说,它仅在其声明至 Else 语句之间可用。如果需要在整个过程中使用变量,则必须在 If/Else/End If 控制结构之外声明该变量。   
 52  
 53变量的块范围是许多结构语言共有的功能。过程局部变量允许定义过程内部变量,从而对结构化编程提供支持,与此类似,块级别变量允许定义代码块内部变量,从而对结构化分解提供支持。   
 54  
 55  
 56  
 57升级   
 58向导   
 59  
 60  
 61如果变量在块内声明,变量将自动移至模块级范围。例如,以下代码:   
 62  
 63If x =1 Then   
 64Dim y As Integer   
 65End If   
 66升级后将变为:   
 67  
 68Dim y As Integer   
 69If x =1 Then   
 70End If   
 71  
 72  
 73新的自动重新实例化   
 74Visual   
 75Basic 6.0 窗体的类变量声明 Dim x As New <classname> 将导致编译器每次引用 x 时生成代码。此代码检查 x 是否为 Nothing;如果是 Nothing,则创建类的新实例。例如,以下代码:   
 76  
 77Dim x As New MyClass   
 78'...   
 79Call x.MyMethod()   
 80等同于:   
 81  
 82Dim x As MyClass   
 83'...   
 84If x Is Nothing Then   
 85Set x = New MyClass   
 86End If   
 87Call x.MyMethod()   
 88即使变量已经设置为 Nothing,在下一次调用时该变量仍将重新实例化。   
 89  
 90Visual Basic.NET   
 91  
 92  
 93窗体的变量声明 Dim x As New <classname> 等同于 Dim x As <classname> = New <classname>。引用通过此语法声明的变量不会生成特殊代码。   
 94  
 95Visual Basic.NET 声明 As New 比 Visual Basic 6.0 中的同一声明更加有效。大多数对这类变量的引用不需要额外的开销。而且,Visual Basic 6.0 的“自动实例化”行为对于发现它的许多编程人员来说非常古怪。   
 96  
 97  
 98  
 99升级   
100向导   
101  
102  
103这极少会成为问题。但是,如果代码尝试使用已设置为 Nothing 的类,将导致运行时异常。该异常很容易检测到。然后,可以方便地修改代码以实例化类的新版本,如下例所示:   
104  
105Dim x As New MyClass   
106x = Nothing   
107x = New MyClass   
108  
109  
110对象终结   
111Visual   
112Basic 6.0 COM 引用计数机制用于垃圾回收对象实例。如果对象不在循环中,当对象不再使用,引用计数会立即检测到此情况,并且运行终结代码。   
113  
114Visual Basic.NET   
115  
116  
117跟踪垃圾回收器从存储在堆栈变量、模块变量和共享变量中的可及引用开始,将对象过一遍。此跟踪进程作为后台任务运行,因此在指向对象的最后一个引用结束和添加新引用之间有一个不定的时间段。   
118  
119在某些情况下,客户端确实需要能够强制某一对象释放资源。CLR 规定这样的对象应当实现 IDisposable 接口,这就提供了 Dispose 方法。当客户端结束对具有 Dispose 方法的对象的使用时,它可以显式调用 Dispose 方法以释放其资源。例如,包装数据库连接的对象应当公开 Dispose 方法。   
120  
121跟踪垃圾回收器能够正确释放引用循环中的对象。此外,跟踪垃圾回收器的性能比引用计数要好得多。   
122  
123  
124  
125升级   
126向导   
127  
128  
129在大多数情况下,这一改变不会导致问题。如果您的代码中使用了资源句柄开放(连接或文件句柄),则必须显式关闭此句柄。此问题易于检测并会导致运行时错误。   
130  
131  
132数组   
133Visual   
134Basic 6.0 数组可以由任何整数数字的上下限限定。如果在声明中未指定下限,将使用 Option Base 语句确定默认下限。   
135  
136Visual Basic.NET   
137  
138  
139为了与其他语言协同操作,所有数组的下限均必须为零。这样就不再需要 Option Base 语句。   
140  
141升级   
142向导   
143  
144  
145ReDim   
146Visual   
147Basic 6.0 Visual Basic 6.0 中的固定大小数组和不定大小数组有所区别。固定大小数组通过 Dim 语句声明,在此语句包括此声明中的数组界限。动态数组在 Dim 语句中声明,不指定界限信息。在使用动态数组之前,需要通过 ReDim 语句重新标注动态数组。在 Visual Basic 6.0 中,ReDim 语句提供了在单个语句中为动态数组声明和分配空间的快捷方法。ReDim 语句是 Visual Basic 6.0 中唯一能够同时声明和初始化变量的语句。   
148  
149  
150  
151Visual Basic.NET   
152  
153  
154ReDim 语句仅用于为数组分配或重新分配空间,而不能用于重新分配数组。这是因为 Visual Basic.NET 中的所有数组均是动态的,在 Visual Basic.NET 中 Dim 语句既可用于声明动态数组,又可用于初始化动态数组。   
155  
156由于所有变量声明均可声明变量并指定变量的初始值,使用 ReDim 同时声明和初始化变量就变得多余和不必要了。只需要 Dim 语句声明变量使语言更加简单、一致性更高。   
157  
158升级   
159向导   
160  
161  
162如果 ReDim() 用于声明数组,在代码中会自动插入相应的声明。但是,最好的方法是您自己先在数组中插入 Dim 语句,因为使用 ReDim 声明数组需要升级工具来推断正确的声明。使用 ReDim 也产生了不便处理的代码,因为数组在两处进行了同一声明。   
163  
164  
165赋值   
166Visual   
167Basic 6.0 赋值形式有两种:Let 赋值(默认)和 Set 赋值。用 Set 语句为 cn 赋值。   
168  
169  
170Visual Basic.NET   
171  
172  
173仅有一种赋值形式。x = y 意味着将变量或属性 y 的值赋给变量或属性 x。对象类型变量的值是对对象实例的引用,因此如果 x 和 y 是引用类型的变量,将执行引用赋值。这种单一形式的赋值减少了语言的复杂性,并使代码可读性更强。   
174  
175升级向导   
176  
177  
178删除 Set 和 Let 语句。解析强类型对象的默认属性,并将属性显式添加到代码中。   
179  
180有关该主题的全面说明,请参阅白皮书《准备将 Visual Basic 6.0 应用程序升级到 Visual Basic.NET》(英文)。   
181  
182  
183And、Or、Xor 和 Not   
184Visual   
185Basic 6.0 And、Or、Xor 和 Not 运算符可以执行逻辑运算或位运算(取决于表达式)。   
186  
187  
188  
189Visual Basic.NET   
190  
191  
192And、Or 和 Xor 仅适用于布尔型。对于 And 和 Or 运算符,如果第一个运算数的值足以确定运算符的结果,则运算符将简化计算。新的运算符 BitOr、BitAnd 和 BitXor 均用于位逻辑运算。Bitxxx 运算符不具有简化作用。   
193  
194  
195  
196升级   
197向导   
198  
199  
200如果 And/Or 语句是非布尔型或者包含函数、方法或属性,此语句将升级为使用兼容性函数,与 Visual Basic 6.0 中的表现形式相同。如果 And/Or 语句是布尔型,此语句将升级为使用本地 Visual Basic.Net 语句。   
201  
202有关该主题的全面说明,请参阅白皮书《准备将 Visual Basic 6.0 应用程序升级到 Visual Basic.NET》(英文)。   
203  
204  
205运算符优先级   
206Visual   
207Basic 6.0 逻辑和位的 And、Or、Xor 和 Not 运算符的优先级高于比较运算符。   
208  
209  
210  
211Visual Basic.NET   
212  
213  
214And、Or、Xor 和 Not 运算符的优先级低于比较运算符,因此 a &gt; b And a &lt; c 将被认为是 (a &gt; b) And (a &lt; c)。新的 BitAnd、BitOr 和 BitXor 运算符的优先级高于比较运算符,因此 a BitAnd &amp;HFFFF &lt;&gt; 0 将被认为是 ((a BitAnd &amp;HFFFF) &lt;&gt; 0)。   
215  
216由于 BitAnd、BitOr 和 BitNot 运算符可以返回数值结果,因此其优先级高于关系运算符,这样,就允许这三个运算符返回的结果与其他值进行比较。   
217  
218  
219  
220升级   
221向导   
222  
223  
224由升级向导处理。有关该主题的全面说明,请参阅白皮书《准备将 Visual Basic 6.0 应用程序升级到 Visual Basic.NET》(英文)。   
225  
226  
227调用过程   
228Visual   
229Basic 6.0 支持两种类型的过程调用:一种使用 Call 语句,要求使用括号括住参数列表;另一种不使用 Call 语句,不能使用括号来括住参数列表。   
230  
231在 Visual Basic 6.0 中的一种常见情况是,开发者调用的过程不使用关键字,而又在参数列表外使用括号。幸运的是,当有一个以上的参数时,编译器会将其作为语法错误检测出来。但是,当仅有一个参数时,单一参数外的括号会将参数变量传递为 ByVal 而不是 ByRef。这会导致难以找到的小错误。   
232  
233  
234  
235Visual Basic.NET   
236  
237  
238在所有情况下参数列表均需要使用括号。   
239  
240  
241  
242升级向导   
243  
244  
245为没有使用括号的过程调用插入括号。   
246  
247  
248静态过程   
249Visual   
250Basic 6.0 通过 Static 关键字可以声明过程,此关键字表明在调用之间保留过程的局部变量。   
251  
252  
253  
254Visual Basic.NET   
255  
256  
257在过程中不支持 Static 关键字,并且所有的静态局部变量均需通过 Static 语句显式声明。   
258  
259需要将过程中的所有变量均声明为静态的情况很少。删除此功能简化了语言,并且提高了可读性,因为局部变量总是位于堆栈中,除非已显式声明为 Static。   
260  
261  
262  
263升级   
264向导   
265  
266  
267如果过程标记为 Static,则所有的局部变量均变为 Static。   
268  
269  
270参数的 ByVal/ByRef 默认值   
271Visual   
272Basic 6.0 参数未指定其默认值为 ByVal 或 ByRef 时,其默认值为 ByRef。   
273  
274  
275  
276Visual Basic.NET   
277  
278  
279&lt;参数未指定其默认值为 ByVal 或 ByRef 时,其默认值为 ByVal。   
280  
281将参数默认值指定为 ByVal 而不指定为 ByRef,可以避免过程错误地修改由调用方传递的变量。这也使得默认的调用规则与赋值一致,以便参数有效地绑定至表达式(通过表达式赋值为正式参数)。   
282  
283请用户注意避免由 Visual Basic 6.0 升级到 Visual Basic.NET 带来的混乱。如果用户输入的参数声明未显式指定其默认值为 ByVal 或 ByRef,IDE 将为其自动添加 ByVal 关键字。   
284  
285  
286  
287升级   
288向导   
289  
290  
291为没有指定 ByVal 或 ByRef 为默认值的参数添加 ByRef。   
292  
293  
294IsMissing 参数和可选参数   
295Visual   
296Basic 6.0 没有默认值的可选 Variant 参数将被初始化为特殊的错误代码,此错误代码可以由 IsMissing 函数检测出来。   
297  
298  
299  
300Visual Basic.NET   
301  
302  
303在 Visual Basic.NET 中要求所有的可选参数均指定默认值。这样可以减少语言中特殊值的数量,从而简化语言。   
304  
305  
306  
307升级   
308向导   
309  
310  
311IsMissing 函数由 IsNothing 函数代替,并且标记有升级警告注释。   
312  
313  
314ParamArray 参数   
315Visual   
316Basic 6.0 当变量传递给 ParamArray 参数时,可以通过被调用的函数修改。不支持 ByVal ParamArray 元素。   
317  
318Visual Basic.NET   
319  
320  
321当变量传递给 ParamArray 参数时,不能通过被调用的函数修改。不支持 ByRef ParamArray 元素。   
322  
323ParamArray 参数最常见的情况是不修改传递给此参数的变量。不支持 ByRef ParamArray 参数简化了 ParamArray 调用规则,因为 ParamArray 参数将被指定为正常数组。这样,ParamArray 参数可以扩展到任何元素类型,同时需要 ParamArray 参数的函数均可通过数组(而不是参数列表)直接调用。</classname></classname></classname></classname></type>
Published At
Categories with Web编程
Tagged with
comments powered by Disqus