c#

位置:IT落伍者 >> c# >> 浏览文章

从Visual Basic 6.0到Visual Basic.NET


发布日期:2022年03月26日
 
从Visual Basic 6.0到Visual Basic.NET

Microsoft Visual BasicNET 是 Microsoft Visual Basic 的后续版本它是基于 NET 框架重新设计的您可以用它来轻松地创建用于 Microsoft Windows 位 操作系统和 Web 的下一代应用程序使用 Visual BasicNET可视化开发 Web 应用程序Web 服务Windows 应用程序和服务器端组件将变得轻而易举此外Visual BasicNET 使用了 Windows 应用程序的 XCOPY 部署方案使您不必再担心 DLL 版本问题随着 Visual BasicNET 的发布DLL 噩梦将成为过去

在设计 Visual BasicNET 时我们着眼于世界各地 Visual Basic 开发者的要求Visual Basic 语言现在是真正的面向对象语言并支持实现继承窗体设计器支持可视化继承并包含窗体自动调整大小资源本地化和访问选项支持等新特性现在的数据工具继续支持 XML 数据并可以共同使用设计时数据绑定和断开数据此外Visual BasicNET 是基于 NET 框架直接创建的因此可以使用所有的平台特性并能够与其他 NET 语言协同工作

在发布这些功能的同时我们对产品的几个方面作了修改本文档介绍了从 Visual Basic 到 Visual BasicNET 的一些变更并解释了进行这些变更的原因本文还介绍 Visual BasicNET 升级向导的功能它是作为产品的一部分提供的工具可以帮助您将现有的应用程序升级为 Visual BasicNET 版本

有关从 Visual Basic 升级到 Visual BasicNET 的其他信息请参阅白皮书《准备将 Visual Basic 应用程序升级到 Visual BasicNET》(英文)此白皮书介绍了升级过程并提供了尽可能顺利升级的建设性意见

语言

Variant

Visual Basic

Variant 是一种特殊的通用数据类型可以包含除定长字符串之外的各类数据Object 变量用作指向对象的指针默认的数据类型为 Variant

Visual BasicNET

公共语言运行时 (CLR) 使用 Object 作为通用数据类型Visual BasicNET 没有继续使用 Variant 作为通用数据类型而是选择采用 CLR 命名规则以避免在跨语言开发时造成混乱仅使用一种通用数据类型将简化类型系统默认的数据类型为 Object

升级向导

将 Variant 数据类型变为 Object因此以下代码

Dim x As Variant

升级后将变为Dim x As Object

Integer 和 Long

Visual Basic

Long 变量存储为带有符号的 位数字而 Integer 变量存储为 位数字

Visual BasicNET

Long 变量存储为带有符号的 位数字Integer 变量存储为 位数字而 Short 变量存储为 位数字 位系统中 位整数操作比 位和 位整数操作都要快这意味着 Integer 将是最有效和最基本的数字类型

由于部分 NET 框架技术以现代的 位和 位技术为基础因此根据新技术更新数据大小是明智之举

升级向导

修改变量的类型因此以下代码

Dim x As IntegerDim y As Long

升级后将变为

Dim x As ShortDim y As Integer

Currency

Visual Basic

Visual Basic 支持 Currency 数据类型您不能将变量声明为 Decimal 类型(虽然变量可以具有子类型 Decimal)

Currency 变量以整数格式存储为 位数字 为标度以将数字表示为定点数其小数点左边为 右边为 这种表示形式可以表示 范围内的数字

Decimal 变量存储为带有符号的 位整数标度为 的不同乘幂 次幂的刻度因子指定了小数点右边的数字位数其范围为 当指数为 时(无小数位数)最大的可能值为 +/当指数为 最大值为 +/最小的非零值为 +/

Visual BasicNET

Currency 数据类型的精度不够无法避免四捨五入的误差因此创建了 Decimal 这种数据类型

升级向导

将 Currency 数据类型转换为 Decimal因此以下代码

Dim x As Currency

升级后将变为

Dim x As Decimal

Date

Visual Basic

Date 变量在内部以 Double 格式存储能够作为 Double 类型的变量操作

Date 变量存储为 IEEE 位浮点数表示从 日到 日的日期和从 :::: 的时间任何可识别的文字日期都可以指定为 Date 变量

当其他数字类型转换为 Date 时小数点左边的值表示日期信息而小数点右边的值表示时间信息午夜为 正午为 整个数值为负表示 日之前的日期

Visual BasicNET

Date 在内部存储为 位整数因此无法直接作为 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 = datToOADate

定长字符串

Visual Basic

除类模块的 Public 变量之外其他变量均可以声明为定长字符串

Visual BasicNET

CLR 第一版不支持定长字符串在后续版本中将添加这一支持功能

升级向导

在大多数情况下不会出现问题假设为定长字符串表现方式则以下代码

Dim MyFixedLengthString As String *

升级后将变为

Dim MyFixedLengthString As New VBFixedLengthString()

有关该主题的全面说明请参阅白皮书《准备将 Visual Basic 应用程序升级到 Visual BasicNET》(英文)

Type

Visual Basic

Type 语句用于定义由用户定义的数据类型

Visual BasicNET

Type 和 UserDefined Type 这两个名称会引起混淆因为类枚举和接口也是可以由用户定义的类型Type 和 UserDefined Type 是从 QuickBasic 遗留下来的在 QuickBasic 中用户可以定义的类型只有结构和记录CLR 使用 Type 这一名称广义地包含所有数据类型

因此在 Visual BasicNET 中 Type 语句将变为 Structure

升级向导

将 Type 语句变为 Structure因此以下代码

Type MyType MyVariable As Integer End Type

升级后将变为

Structure MyType Dim MyVariable As Short End Structure

用户定义类型存储

Visual Basic

用户定义的数据类型可以包含某种数据类型数组或先前定义的用户定义类型的一个或多个元素在 Visual Basic 它们存储在连续的内存块中

Visual BasicNET

格式是最有效的它可能位于一段连续的内存也可能不结构可以被标记为封送处理属性以确保能够作为连续内存块传递到 COM 组件

升级向导

在所有需要添加封送处理属性的位置API 均标记有 TODO 注释(属性不是自动添加的只有将结构传递到 API 时才需要它们

True

Visual Basic

True 的值为

Visual BasicNET

True 的值为

鑒于语言的协同操作需要一种适用于所有语言的一致表示法

升级向导

如果将布尔值强制转换为非布尔值代码将标记有升级警告例如以下代码

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

变量均初始化为 Empty当用于数值表达式时变量将自动转换为零当用于字符串表达式时则自动转换为空字符串

Visual BasicNET

对象变量均初始化为 Nothing当用于数值表达式时变量将自动转换为零当用于字符串表达式时将自动转换为空字符串使用 Nothing 代替特殊的 Empty 值可以降低语言的复杂性语言协同操作性也更强

升级向导

Null 和 Null 传播

Visual Basic

Null 值为 Variant 的子类型表示变量不包含有效数据Null 值通过表达式和函数传播如果表达式的任一部分为 Null则整个表达式为 Null将 Null 作为参数传递给大多数函数时这些函数也将返回 Null

Visual BasicNET

不支持 Null 传播使用 ADONET 对数据进行编程的模型用于在检索字段的值之前先检查字段的值是否为 Null包含 null 的变量将作为 DBNull 类型的对象封送处理至 CLR

Visual BasicNET 处理 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

DefBoolDefByteDefIntDefLngDefCurDefSngDefDblDefDecDefDateDefStrDefObj 和 DefVar 语句用于在模块级设置变量参数和过程返回类型(以指定字符开始)的默认数据类型

Visual BasicNET

避免使用隐式类型声明提高了代码的可读性和可靠性

升级向导

将变量类型的显式声明插入代码例如以下代码

DefStr az

Sub MySub

s = Hello

End Sub

升级后将变为

Sub MySub

Dim s As String

s = Hello

End Sub

块内的局部变量

Visual Basic

从包含声明的行至过程结束的范围内局部变量均可见

Visual BasicNET

Visual BasicNET 支持变量的块范围这意味着从包含声明的行开始至出现声明的块结束局部变量均可见例如

Sub Test(x As Integer)

If x < Then

Dim y As Integer = x

Else

End If

End Sub

以上示例中的变量 y 仅在声明该变量的块中可用更确切地说它仅在其声明至 Else 语句之间可用如果需要在整个过程中使用变量则必须在 If/Else/End If 控制结构之外声明该变量

变量的块范围是许多结构语言共有的功能过程局部变量允许定义过程内部变量从而对结构化编程提供支持与此类似块级别变量允许定义代码块内部变量从而对结构化分解提供支持

升级向导

如果变量在块内声明变量将自动移至模块级范围例如以下代码

If x = Then

Dim y As Integer

End If

升级后将变为

Dim y As Integer

If x = Then

End If

新的自动重新实例化

Visual Basic

窗体的类变量声明 Dim x As New <classname> 将导致编译器每次引用 x 时生成代码此代码检查 x 是否为 Nothing如果是 Nothing则创建类的新实例例如以下代码

Dim x As New MyClass

Call xMyMethod()

等同于

Dim x As MyClass

If x Is Nothing Then

Set x = New MyClass

End If

Call xMyMethod()

即使变量已经设置为 Nothing在下一次调用时该变量仍将重新实例化

Visual BasicNET

窗体的变量声明 Dim x As New <classname> 等同于 Dim x As <classname> = New <classname>引用通过此语法声明的变量不会生成特殊代码

Visual BasicNET 声明 As New 比 Visual Basic 中的同一声明更加有效大多数对这类变量的引用不需要额外的开销而且Visual Basic 自动实例化行为对于发现它的许多编程人员来说非常古怪

升级向导

这极少会成为问题但是如果代码尝试使用已设置为 Nothing 的类将导致运行时异常该异常很容易检测到然后可以方便地修改代码以实例化类的新版本如下例所示

Dim x As New MyClass

x = Nothing

x = New MyClass

对象终结

Visual Basic

COM 引用计数机制用于垃圾回收对象实例如果对象不在循环中当对象不再使用引用计数会立即检测到此情况并且运行终结代码

Visual BasicNET

跟蹤垃圾回收器从存储在堆栈变量模块变量和共享变量中的可及引用开始将对象过一遍此跟蹤进程作为后台任务运行因此在指向对象的最后一个引用结束和添加新引用之间有一个不定的时间段

在某些情况下客户端确实需要能够强制某一对象释放资源CLR 规定这样的对象应当实现 IDisposable 接口这就提供了 Dispose 方法当客户端结束对具有 Dispose 方法的对象的使用时它可以显式调用 Dispose 方法以释放其资源例如包装数据库连接的对象应当公开 Dispose 方法

跟蹤垃圾回收器能够正确释放引用循环中的对象此外跟蹤垃圾回收器的性能比引用计数要好得多

升级向导

在大多数情况下这一改变不会导致问题如果您的代码中使用了资源句柄开放(连接或文件句柄)则必须显式关闭此句柄此问题易于检测并会导致运行时错误

数组

Visual Basic

数组可以由任何整数数字的上下限限定如果在声明中未指定下限将使用 Option Base 语句确定默认下限

Visual BasicNET

为了与其他语言协同操作所有数组的下限均必须为零这样就不再需要 Option Base 语句

升级向导

ReDim

Visual Basic

Visual Basic 中的固定大小数组和不定大小数组有所区别固定大小数组通过 Dim 语句声明在此语句包括此声明中的数组界限动态数组在 Dim 语句中声明不指定界限信息在使用动态数组之前需要通过 ReDim 语句重新标注动态数组在 Visual Basic ReDim 语句提供了在单个语句中为动态数组声明和分配空间的快捷方法ReDim 语句是 Visual Basic 中唯一能够同时声明和初始化变量的语句

Visual BasicNET

ReDim 语句仅用于为数组分配或重新分配空间而不能用于重新分配数组这是因为 Visual BasicNET 中的所有数组均是动态的在 Visual BasicNET 中 Dim 语句既可用于声明动态数组又可用于初始化动态数组 由于所有变量声明均可声明变量并指定变量的初始值使用 ReDim 同时声明和初始化变量就变得多余和不必要了只需要 Dim 语句声明变量使语言更加简单一致性更高

升级向导

如果 ReDim() 用于声明数组在代码中会自动插入相应的声明但是最好的方法是您自己先在数组中插入 Dim 语句因为使用 ReDim 声明数组需要升级工具来推断正确的声明使用 ReDim 也产生了不便处理的代码因为数组在两处进行了同一声明

赋值

Visual Basic

赋值形式有两种Let 赋值(默认)和 Set 赋值用 Set 语句为 cn 赋值

Visual BasicNET

仅有一种赋值形式x = y 意味着将变量或属性 y 的值赋给变量或属性 x对象类型变量的值是对对象实例的引用因此如果 x 和 y 是引用类型的变量将执行引用赋值这种单一形式的赋值减少了语言的复杂性并使代码可读性更强

升级向导

删除 Set 和 Let 语句解析强类型对象的默认属性并将属性显式添加到代码中

有关该主题的全面说明请参阅白皮书《准备将 Visual Basic 应用程序升级到 Visual BasicNET》(英文)

AndOrXor 和 Not

Visual Basic

AndOrXor 和 Not 运算符可以执行逻辑运算或位运算(取决于表达式)

Visual BasicNET

AndOr 和 Xor 仅适用于布尔型对于 And 和 Or 运算符如果第一个运算数的值足以确定运算符的结果则运算符将简化计算新的运算符 BitOrBitAnd 和 BitXor 均用于位逻辑运算Bitxxx 运算符不具有简化作用

升级向导

如果 And/Or 语句是非布尔型或者包含函数方法或属性此语句将升级为使用兼容性函数与 Visual Basic 中的表现形式相同如果 And/Or 语句是布尔型此语句将升级为使用本地 Visual BasicNet 语句

有关该主题的全面说明请参阅白皮书《准备将 Visual Basic 应用程序升级到 Visual BasicNET》(英文)

运算符优先级

上一篇:用VisualC#中轻松浏览数据库记录

下一篇:C#用回溯法找出n个自然数中取r个数的全排列