ASP FileSystemObject 对象模型

零、FileSystemObject 对象模型的对象

对象

对象描述
FileSystemObject主对象,提供创建、删除及访问其他对象的方法(如CreateFolder、GetDrive等)。
Drive表示物理或网络驱动器(如硬盘、CD-ROM),提供容量、可用空间、类型等信息收集功能。
Folder用于文件夹的创建、删除、移动及路径查询(如SubFolders属性可遍历子文件夹)。
File对应单个文件,支持读写、复制等操作,与Folder对象方法类似但目标不同。
TextStream专用于文本文件的读写操作(不支持二进制文件,需使用Open命令处理)。
Dictionary用于组织数据结构。一个字典中有多个元素,每个元素都由两部分组成,一个叫键(key),一个叫项(item)。 键相当于是这个元素独一无二的标识,就像一个词典里的每个词条都只会出现一次,所以键是不会重复的。项就是这个元素的内容,内容可以任意改变,所以项是可以重复的。

一、FileSystemObject 对象的属性和方法

属性

属性描述
Drives返回本地计算机上所有驱动器对象的集合。

方法

方法描述
BuildPath将一个名称追加到已有的路径后
CopyFile从一个位置向另一个位置拷贝一个或多个文件。
CopyFolder从一个位置向另一个位置拷贝一个或多个文件夹。
CreateFolder创建新文件夹。
CreateTextFile创建文本文件,并返回一个 TextStream 对象。
DeleteFile删除一个或者多个指定的文件。
DeleteFolder删除一个或者多个指定的文件夹。
DriveExists检查指定的驱动器是否存在。
FileExists检查指定的文件是否存在。
FolderExists检查某个文件夹是否存在。
GetAbsolutePathName针对指定的路径返回从驱动器根部起始的完整路径。
GetBaseName返回指定文件或者文件夹的基名称。
GetDrive返回指定路径中所对应的驱动器的 Drive 对象。
GetDriveName返回指定的路径的驱动器名称。
GetExtensionName返回在指定的路径中最后一个成分的文件扩展名。
GetFile返回一个针对指定路径的 File 对象。
GetFileName返回在指定的路径中最后一个成分的文件名。
GetFolder返回一个针对指定路径的 Folder 对象。
GetParentFolderName返回在指定的路径中最后一个成分的父文件名称。
GetSpecialFolder返回某些 Windows 的特殊文件夹的路径。
GetTempName返回一个随机生成的文件或文件夹。
MoveFile从一个位置向另一个位置移动一个或多个文件。
MoveFolder从一个位置向另一个位置移动一个或多个文件夹。
OpenTextFile打开文件,并返回一个用于访问此文件的 TextStream 对象。

二、Drive 对象的属性

属性描述
AvailableSpace向用户返回在指定的驱动器或网络共享驱动器上的可用空间容量。
DriveLetter返回识别本地驱动器或网络共享驱动器的大写字母。
DriveType返回指定驱动器的类型。
FileSystem返回指定驱动器所使用的文件系统类型。
FreeSpace向用户返回在指定的驱动器或网络共享驱动器上的剩余空间容量。
IsReady如果指定驱动器已就绪,则返回 true。否则返回 false。
Path返回其后有一个冒号的大写字母,用来指示指定驱动器的路径名。
RootFolder返回一个文件夹对象,该文件夹代表指定驱动器的根文件夹。
SerialNumber返回指定驱动器的序列号。
ShareName返回指定驱动器的网络共享名。
TotalSize返回指定的驱动器或网络共享驱动器的总容量
VolumeName设置或者返回指定驱动器的卷标名

三、Folder 对象的集合、属性以及方法

集合

集合描述
Files返回指定文件夹中所有文件夹的集合。
SubFolders返回指定文件夹中所有子文件夹的集合。

属性

属性描述
Attributes设置或返回指定文件夹的属性。
DateCreated返回指定文件夹被创建的日期和时间。
DateLastAccessed返回指定文件夹最后被访问的日期和时间。
DateLastModified返回指定文件夹最后被修改的日期和时间。
Drive返回指定文件夹所在的驱动器的驱动器字母。
IsRootFolder假如文件夹是根文件夹,则返回 ture,否则返回 false。
Name设置或返回指定文件夹的名称。
ParentFolder返回指定文件夹的父文件夹。
Path返回指定文件的路径。
ShortName返回指定文件夹的短名称。(8.3 命名约定)
ShortPath返回指定文件夹的短路径。(8.3 命名约定)
Size返回指定文件夹的大小。
Type返回指定文件夹的类型。

方法

方法描述
Copy把指定的文件夹从一个位置拷贝到另一个位置。
Delete删除指定文件夹。
Move把指定的文件夹从一个位置移动到另一个位置。
CreateTextFile在指定的文件夹创建一个新的文本文件,并返回一个 TextStream 对象以访问这个文件。

四、File 对象的属性和方法

属性

属性描述
Attributes设置或返回指定文件的属性。
DateCreated返回指定文件创建的日期和时间。
DateLastAccessed返回指定文件最后被访问的日期和时间。
DateLastModified返回指定文件最后被修改的日期和时间。
Drive返回指定文件或文件夹所在的驱动器的驱动器字母。
Name设置或返回指定文件的名称。
ParentFolder返回指定文件或文件夹的父文件夹对象。
Path返回指定文件的路径。
ShortName返回指定文件的短名称(8.3 命名约定)。
ShortPath返回指定文件的短路径(8.3 命名约定)。
Size返回指定文件的尺寸(字节)。
Type返回指定文件的类型。

方法

方法描述
Copy把指定文件从一个位置拷贝到另一个位置。
Delete删除指定文件。
Move把指定文件从一个位置移动到另一个位置。
OpenAsTextStream打开指定文件,并返回一个 TextStream 对象以便访问此文件。

五、TextStream 对象的属性和方法

属性

属性描述
AtEndOfLine在 TextStream 文件中,如果文件指针正好位于行尾标记的前面,那么该属性值返回 True;否则返回 False。
AtEndOfStream如果文件指针在 TextStream 文件末尾,则该属性值返回 True;否则返回 False。
Column返回 TextStream 文件中当前字符位置的列号。
Line返回 TextStream 文件中的当前行号。

方法

方法描述
Close关闭一个打开的 TextStream 文件。
Read从一个 TextStream 文件中读取指定数量的字符并返回结果(得到的字符串)。
ReadAll读取整个 TextStream 文件并返回结果。
ReadLine从一个 TextStream 文件读取一整行(到换行符但不包括换行符)并返回结果。
Skip当读一个 TextStream 文件时跳过指定数量的字符。
SkipLine当读一个 TextStream 文件时跳过下一行。
Write写一段指定的文本(字符串)到一个 TextStream 文件。
WriteLine写入一段指定的文本(字符串)和换行符到一个 TextStream 文件中。
WriteBlankLines写入指定数量的换行符到一个 TextStream 文件中。

六、Dictionary 对象的属性和方法

属性

属性描述
CompareMode设置或返回用于在 Dictionary 对象中比较键的比较模式。
Count返回 Dictionary 对象中键/项目对的数目。
Item设置或返回 Dictionary 对象中一个项目的值。
Key为 Dictionary 对象中已有的键值设置新的键值。

方法

方法描述
Add向 Dictionary 对象添加新的键/项目对。
Exists返回一个逻辑值,这个值可指示指定的键是否存在于 Dictionary 对象中。
Items返回 Dictionary 对象中所有项目的一个数组。
Keys返回 Dictionary 对象中所有键的一个数组。
Remove从 Dictionary 对象中删除指定的键/项目对。
RemoveAll删除 Dictionary 对象中所有的键/项目对。

为类添加集合

一、首先创建三个基础类(ClassA、ClassB、ClassC)

‘ ClassA.cls
‘(空类,可根据需要添加属性或方法,见 建立类模块

‘ ClassB.cls
‘(空类,可根据需要添加属性或方法,见 建立类模块

‘ ClassC.cls
‘(空类,可根据需要添加属性或方法,见 建立类模块

二、创建主类(MainClass)包含三个集合

‘ MainClass.cls
Option Explicit

Private m_colItemsA As Collection
Private m_colItemsB As Collection
Private m_colItemsC As Collection

‘ 类初始化时创建集合
Private Sub Class_Initialize()
Set m_colItemsA = New Collection
Set m_colItemsB = New Collection
Set m_colItemsC = New Collection
End Sub

‘ 添加ClassA实例到集合A
Public Sub AddItemA(objA As ClassA)
m_colItemsA.Add objA
End Sub

‘ 添加ClassB实例到集合B
Public Sub AddItemB(objB As ClassB)
m_colItemsB.Add objB
End Sub

‘ 添加ClassC实例到集合C
Public Sub AddItemC(objC As ClassC)
m_colItemsC.Add objC
End Sub

‘ 获取集合A(只读)
Public Property Get ItemsA() As Collection
Set ItemsA = m_colItemsA
End Property

‘ 获取集合B(只读)
Public Property Get ItemsB() As Collection
Set ItemsB = m_colItemsB
End Property

‘ 获取集合C(只读)
Public Property Get ItemsC() As Collection
Set ItemsC = m_colItemsC
End Property

‘ 清理资源
Private Sub Class_Terminate()
Set m_colItemsA = Nothing
Set m_colItemsB = Nothing
Set m_colItemsC = Nothing
End Sub

三、使用示范

Dim mainObj As New MainClass
Dim objA As New ClassA
Dim objB As New ClassB
Dim objC As New ClassC

‘ 添加对象到各个集合
mainObj.AddItemA objA
mainObj.AddItemB objB
mainObj.AddItemC objC

‘ 遍历集合示例
Dim item As Object
For Each item In mainObj.ItemsA
‘ 处理ClassA实例
Next

For Each item In mainObj.ItemsB
‘ 处理ClassB实例
Next

For Each item In mainObj.ItemsC
‘ 处理ClassC实例
Next

四、代码说明

  1. 三个基础类(ClassA/B/C)可根据实际需求添加成员
  2. MainClass使用Collection对象管理三个不同类型的集合
  3. 通过AddItemX方法确保类型安全,只能添加指定类型的实例
  4. 通过只读属性ItemsX暴露集合的访问
  5. 在Class_Terminate中释放集合资源
  6. 使用For Each循环可以方便地遍历集合成员

五、注意事项

VB6的集合是1-based索引(从1开始),如果需要更强大的集合操作,可以考虑使用Dictionary对象或自定义集合类。

让一个类成为另一个类的属性

‘一、建立子类 CAddress.cls
Private m_Street As String
Private m_City As String

Public Property Get Street() As String
Street = m_Street
End Property

Public Property Let Street(ByVal sStreet As String)
m_Street = sStreet
End Property

Public Property Get City() As String
City = m_City
End Property

Public Property Let City(ByVal sCity As String)
m_City = sCity
End Property

‘ 二、建立父类 CPerson.cls
Private m_Address As CAddress ‘ 声明 CAddress 类型的私有变量

‘ 自动初始化 CAddress 实例
Private Sub Class_Initialize()
Set m_Address = New CAddress
End Sub

‘ 清理资源
Private Sub Class_Terminate()
Set m_Address = Nothing
End Sub

‘ 通过 Property Get 公开 CAddress 实例
Public Property Get Address() As CAddress
Set Address = m_Address
End Property

‘ 可选:允许外部设置 CAddress 实例
Public Property Set Address(ByVal objAddress As CAddress)
Set m_Address = objAddress
End Property

‘ 三、在窗体或模块中使用:
Dim person As CPerson
Set person = New CPerson

‘ 设置地址属性
With person.Address
.Street = “123 Main St”
.City = “New York”
End With

‘ 读取地址属性
MsgBox “地址:” & person.Address.Street & “, ” & person.Address.City

‘四、注意事项

Set person.Address = New CAddress ‘ 正确
person.Address = New CAddress ‘ 错误(缺少 Set)

建立类模块

‘ 一、类模块代码

‘ 类名: clsWire
‘ 包含8个参数、2个方法、1个事件

Option Explicit

‘ —————————-
‘ 1. 定义私有变量(8个参数)
‘ —————————-
Private pMaterial As String ‘ 材料
Private pLength As Double ‘ 长度
Private pDiameter As Double ‘ 直径
Private pVoltage As Double ‘ 电压
Private pCurrent As Double ‘ 电流
Private pResistance As Double ‘ 电阻
Private pTemperature As Double ‘ 温度
Private pIsInsulated As Boolean ‘ 是否有绝缘层

‘ —————————-
‘ 2. 定义事件
‘ —————————-
Event StatusChanged(ByVal Message As String)

‘ —————————-
‘ 类初始化(设置默认值)
‘ —————————-
Private Sub Class_Initialize()
pMaterial = “Copper” ‘ 默认材料为铜
pLength = 0
pDiameter = 0
pVoltage = 0
pCurrent = 0
pResistance = 0
pTemperature = 25 ‘ 默认温度25°C
pIsInsulated = False
End Sub

‘ —————————-
‘ 属性定义(8个参数)
‘ —————————-
Public Property Get Material() As String
Material = pMaterial
End Property
Public Property Let Material(ByVal Value As String)
pMaterial = Value
End Property

Public Property Get Length() As Double
Length = pLength
End Property
Public Property Let Length(ByVal Value As Double)
pLength = Value
End Property

Public Property Get Diameter() As Double
Diameter = pDiameter
End Property
Public Property Let Diameter(ByVal Value As Double)
pDiameter = Value
End Property

Public Property Get Voltage() As Double
Voltage = pVoltage
End Property
Public Property Let Voltage(ByVal Value As Double)
pVoltage = Value
End Property

Public Property Get Current() As Double
Current = pCurrent
End Property
Public Property Let Current(ByVal Value As Double)
pCurrent = Value
End Property

Public Property Get Resistance() As Double
Resistance = pResistance
End Property
Public Property Let Resistance(ByVal Value As Double)
pResistance = Value
End Property

Public Property Get Temperature() As Double
Temperature = pTemperature
End Property
Public Property Let Temperature(ByVal Value As Double)
pTemperature = Value
End Property

Public Property Get IsInsulated() As Boolean
IsInsulated = pIsInsulated
End Property
Public Property Let IsInsulated(ByVal Value As Boolean)
pIsInsulated = Value
End Property

‘ —————————-
‘ 方法1:计算功率
‘ —————————-
Public Function CalculatePower() As Double
CalculatePower = pVoltage * pCurrent ‘ P = V * I
RaiseEvent StatusChanged(“功率计算完成: ” & CalculatePower & “W”)
End Function

‘ —————————-
‘ 方法2:检查安全性
‘ —————————-
Public Sub CheckSafety()
Dim msg As String
If pTemperature > 80 Then
msg = “警告:温度过高(” & pTemperature & “°C)!”
ElseIf pCurrent > 10 Then
msg = “警告:电流超过安全阈值!”
Else
msg = “系统状态正常”
End If
RaiseEvent StatusChanged(msg) ‘ 触发事件
End Sub

‘ 二、调用

‘ 在窗体代码中:
Dim WithEvents myWire As clsWire ‘ 必须使用 WithEvents 捕获事件

Private Sub Form_Load()
Set myWire = New clsWire
myWire.Voltage = 220
myWire.Current = 5
myWire.Temperature = 75

‘ 调用方法
Debug.Print “功率:” & myWire.CalculatePower()
myWire.CheckSafety

End Sub

‘ 处理事件
Private Sub myWire_StatusChanged(ByVal Message As String)
MsgBox Message, vbInformation, “导线状态”
End Sub

Visual Basic .NET

概述

Visual Basic .NETVB.NET)是.NET Framework框架下的一种多重编程范式高级语言。

VB.NET,是微软公司于2002年作为原有的Visual Basic的继承者而推出。虽然自2005年起,语言名称中的“.NET”就已经被去掉了。但为了与VB 6.0及以前版本的Visual Basic进行区分,“Visual Basic .NET”的名字仍然被社会公众用来指代VB 7.0及以后的Visual Basic。VB.NET与C#同为.Net Framework框架下两种主要的程序设计语言,都是为了调用.Net Framework的类库资源,因此两种语言具有很高的对应性,数据类型、控制结构与语言特性都存在一一对应,容易把源代码从一种语言对译为另一种语言。

微软公司的集成开发环境Visual Studio是最为广泛使用的VB.NET开发工具。然而Visual Studio的大部分版本都是价格不菲的商业软件,除了Express版本和Visual Studio Community(以上两者皆为免费软件)。除了Visual Studio,SharpDevelop和Mono也是可用的VB.NET开发环境。

数据类型与字面常量表示

VB.Net的数据类型,实际上是.Net Framework定义的数据类型。

类型名字节长度取值范围表示法
Short2字节-32768~32767number S
Integer4字节-2 147 48 3 648~2 147 483 647number I
Long8字节-9223372036854775808 ~ 9223372036854775807number& numberL
Single4字节7位有效数字num! numberF
Double8字节15/16位有效数字id# numberR
Decimal16字节29位有效数字id@ numberD
Currency8字节小数点右4位,左15位number@
Byte1字节0-255
Char2字节UTF-16字符“d”C
DateTime8字节0001-01-01T00:00:00.000 ~ 9999-12-31T23.59.59.999#4/102008 06:01:23.456 PM#
Boolean2字节True(-1) False(0)
StringUBSTR, 字符数量*2+2UTF-16字符串“Hello”$
Object4字节
Variant

此外,还有SByte、UShort、UInteger、ULong等无符号数据类型。

&O123表示八进制;&H123表示十六进制。

语法特性

VB使用的名字是大小写不敏感的。但是,CLR是大小写敏感的。所以建议保持一致的大小写。

空值

VB自版本5以后的数据类型来源于COM,而其根源是OLE数据类型。

  • Nothing(C#的null)表示Object类型的变量(即COM中的IDispatch指针,VB中的所有类和控件均由IDispatch派生)为空。对于引用型变量,表示未绑定到一个物理实体对象。
  • Empty表示VARIANT类型变量未初始化(即COM中的VARIANT结构体中的VT成员值为VT_EMPTY)。
  • Null表示VARIANT类型变量已初始化,其值为Null,这时COM中的VARIANT结构体中的VT成员值为VT_NULL。通常是所要表示的值不存在或者有问题不合规。实际上,一个引用型变量如果被赋值为Null,则它绑定的地址为0x0000
  • 零长度字符串(空字符串)需要分配内存,只不过内存(即COM中的BSTR字符串)头4个字节记录的长度为0。VB.Net定义了一个Public Shared Readonly Empty As String = “”。对于仅声明但未实例化的String对象,实际上都绑定到String.Empty对象上。
  • vbNullString没有分配数据内存,实际上定义为Dim *vbNullString As String = Nothing。但又规定了字符串比较时vbNullString = “”为真。

在与空值做比较时,需要区分各种不同用法:

  • 对象(引用型变量)是否为Nothing,可用IsNothing(对象名),对象名Is Nothing,对象名IsNot Nothing等
  • 在比较数据库的一个字段的值是否为空,在.Net中应该用IsDBNull函数或Convert.IsDBNull方法。例如IsDBNull(recordSet(“Column1”).Value))或者recordSet(“Column1”).Value=DBNull.Value。因为DBNull是派生自Object的一个类,DBNull.Value是它的唯一的值。而数据库中的字段值,在DataRow中总是表示为Object,永远不可能为nothing。
  • 比较字符串对象是否为空串,实际上规定了下述三种是等效的:
    • 对象名 = “”
    • 对象名 = String.Empty
    • 对象名 = vbNullString

对于可空类型,实际上是Nullable(Of T)泛型结构。例如,下述三行等价:

Dim ridesBusToWork1? As Boolean
Dim ridesBusToWork2 As Boolean?
Dim ridesBusToWork3 As Nullable(Of Boolean)

比较表达式someVar = Nothing的结果永远是Nothing,应该用someVar.HasValue()方法去判断是否为空,或者用Is或IsNot关键字。

数组

Dim arr([upperLimit]) As dataType = new dataType([upperLimit]) {[initialValues]} '声明数组
arr(index) = value   '使用数组

数组的下标开始自0,这遵从了.NET的标准。如果不指定数组的下标上界,则为动态数组,其长度可以动态调整。

结构控制语句

分支语句

  • If语句
If 条件 Then
    语句
ElseIf 条件 Then
    语句
Else
    语句
End If
  • Switch语句
Select Case Variable
     Case Value1
         Statements
     Case Value2
         Statements
     Case Value3
         Statements
     ...
     Case Else
         Statements
End Select

循环语句

包括下述几种:

  • For…Next循环
For varName = 初值 To 终值 [Step 步长]
    循环体语句
Next varName
  • Do循环
Do [{While|Until} condition]
   statements
   [Exit Do]
Loop

Do
  statements
  [Exit Do]
  statements
Loop [{While|Until} condition]
  • While循环
While condition
   statements
   [Exit While]
   statemenst
End While
  • For Each…Next循环
For Each element in group
    statements
Next [element]

Yield语句

实现迭代器遍历一个序列,每次获取一个返回值。迭代器可以作为一个方法或属性的get访问器,其中的Yield 语句返回迭代器的返回值,并记住当前执行的位置。下次再调用迭代器,从该执行位置恢复执行,直至迭代器代码执行完或者遇到Exit Function或Return语句。编译器把迭代器作为一个状态机的类。

Sub Main()
    Dim days As New DaysOfTheWeek()
    For Each day As String In days
        Console.Write(day & " ")
    Next 
    ' Output: Sun Mon Tue Wed Thu Fri Sat
    Console.ReadKey()
End Sub 

Private Class DaysOfTheWeek
    Implements IEnumerable

    Public days =
        New String() {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}

    Public Iterator Function GetEnumerator() As IEnumerator _
        Implements IEnumerable.GetEnumerator

        ' Yield each day of the week. 
        For i As Integer = 0 To days.Length - 1
            Yield days(i)
        Next 
    End Function 
End Class

面向对象

面向对象时,类的声明示例:

Public Class className [Inherits bassClassName]
    Public varName As Integer '資料成員
    Public [ReadOnly/WriteOnly] Property propertyName() As Integer '屬性
        Public Get
            Return m_var
        End Get
        Public Set(ByVal value As Integer) 
            m_var=value
        End  Set
    End Property
    Public Sub subName(ByVal param1 As Integer) '方法
    End Sub
    Public Function funcName(ByVal param2 As Integer ) As Integer '函數
         Return 101
    End Function
    [atrributive_list][accessibiliby][Shadows]Event eventName([Parameter]) [Implements interfaces.event] '事件
    Public Sub new([Parameter]) '類的構造子(constructor),可以有多個(即可以重載)
    End Sub
End Class

上述示例中的Public关键字表示可访问性(accessibility),表示可以被任意代码访问;它可以替换为其他的可访问性:Private(仅限该Class自身访问)、Friend(仅限同一项目中的代码访问)、Protected(仅限自身或派生类访问)、Protected Friend等。如果使用ReadOnly,则表示数据成员或属性是只读;WriteOnly表示只写。Shadows关键字表示覆盖父类中同名(但不一定参数相同)的Event。使用关键字MyBase引用基类。

类可用继承修饰符:NotInheritable关键字,表示该类不能做基类;MustInherit关键字,表示这是一个抽象类。

类的属性与方法能否被覆盖:Overridable关键字表示可被覆盖;Overrides关键字表示覆盖了基类中同名的方法或属性;NotOverridable关键字表示不可覆盖;MustOverride表示方法或属性仅声明没有实现,这时该类必须有MustInherit修饰符,是一个抽象类或者接口,仅能包含属性、方法、函数的声明。

如同其他.Net语,Visual Basic不允许多重继承,但可以同时实现多个interface。

接口(interface)

接口是一类特殊的抽象类,不能包括可运行代码与类的数据成员的声明:

    Interface interfaceName
       Event eventName([param])
       Property [ReadOnly/WriteOnly] propertyName As typeName
       Function funcName([param]) As returnTypeName
    End Interface

接口中这些成员都强制是Public可访问性。

实现一个接口,使用Implements关键字:

Public Function GetEnumerator() As IEnumerator _
        Implements IEnumerable.GetEnumerator

多态(Polymetric)

基于继承的多态,是指用基类类型的变量绑定不同的子类对象,这样调用基类变量的方法,在运行时动态确定实际运行了哪个派生类的同名的方法。多态的优点是可以针对基类(或接口)的方法来写一个通用的过程或者数据容器,适用于各种不同的派生类的具体实现。

委托(Delegate)

委托本质上是一种Class,派生自System.Delegate,包含了三部分数据:一个类对象的地址、该对象所属类的一个方法的地址,以及另一个委托的引用(reference)。前两部分可以实现对一个类对象的方法的调用;第三部分把委托形成一个链表,使其依次被调用运行。如下声明了一个委托:

 Delegate Sub PlayHandler(ByVal sender As Object, ByVal e As System.EventArgs)

委托常用于事件处理(Event Handler)。.Net Framework的事件是类的属性(实际上是一个嵌套类),用于封装参数格式固定的委托;该委托的参数总是为(ByVal sender As Object, ByVal e as System.EventArgs),返回值为void(即Sub类型)。例如:

 Public Class clsName
    Public Event monitor As PlayHandler
 End Class


对一个具体的实例,可以给它的事件在运行时动态追加上一个或多个事件处理函数:

 AddHandlerins.monitor, AddressOf playHandle_1

AddHandle指向引发事件的对象;AddressOf把一个函数或过程名转化为一个隐式创建的委托实例,用于确定该事件对象所要调用的事件进程。在AddressOf关键字可隐式创建一个引用特定过程的委托的实例。

程序可以抛出一个事件:

 Dim WithEvents e As New System.EventArgs
 Dim ins As New clsName
 RaiseEvent ins.monitor(ins,e)

using语句

using语句,定义一个范围,在范围结束时自动释放对象所占用的资源。

Using conn As New SqlConnection'當在某個代碼段中使用了類的例項,而希望無論因為什麼原因,只要離開了這個代碼段就自動呼叫這個類例項的Dispose。
   '执行代码
End Using

自动属性

例如:

Public Property pa As String=""

对象初始化器

集合(Collection)对象的初始化与普通类对象的属性初始化,分别使用From与With关键字。例如:

    Public Class Person
        Public Property age As Integer
        Public Property Name As String
    End Class

    Dim personList As New List(Of Person) From {
        New Person With {.Name = "Qiang", .age = 24},
        New Person With {.Name = "Wei", .age = 42}
        }

匿名类型

例如:

Dim people = New With {.name="kyo", .age=22}

匿名函数或lambda表达式

即无名的函数或过程,作为表达式的值。可以写为一行或多行。例如:

Dim func1=Function(i As integer) i+10
Dim action = sub()
  End Sub
Dim func2 = Function()
  End Function

可以在声明匿名函数的同时调用它。单行的lambda表达式不能使用Return关键字,其返回类型是自动推导得出;其参数要么都是用As关键字指明类型,要么全部是自动推导出类型。

lambda表达式在定义时可以使用所在上下文(context,即C++语言的闭包closure)的局部变量、参数、属性、Me等等的值,即使lambda表达式离开了定义时所在的context,这些被使用的局部变量等的值仍然有效。这是因为lambda表达式在定义时把所用到的context的值保存到它自己的定义类中。lambda表达式可以嵌套定义。

扩展方法

例如:

Imports System.Runtime.CompilerServices
 Public Function funcName(ByVal ins As className) As String
    'Do something
End Function

异常处理

Try
   ' write the condition here
Catch ex As Exception When condition
   ' Handle Exception when a specific condition is true
Catch ex As Exception
   ' Handle Exception
Finally
   ' Cleanup, close connections etc
   ' NB this code is always executed regardless of if an Exception was raised or not!
End Try

LINQ

From element [ As type ] In collection [, element2 [ As type2 ] In collection2 [, ... ] ] [Where 表达式]

例子(Hello World)

这里给出了一个Hello World的例子。通过它们您可以更好地理解Visual Basic的特性。(此源代码运行于命令行下)

Module Mdl_Main
    Sub Main()
        Console.WriteLine("Hello World")
    End Sub
End Module

这个程序能输出 Hello World 

Module Mdl_Main

第一行是模块定义,命名空间的定义一般可以省略。VB.NET中,所有函数,过程与变量的声明都必须在模块或者类的内部,而不能直接存在于命名空间内部。

Sub Main()

第二行定义了名为Main的过程。一般来说,“Sub Main()”是程序的入口点。

Console.WriteLine("Hello World")

第三行输出“Hello World”。

End Sub

第四行结束了过程Main的定义。

End Module

第五行结束了模块Mdl_Main的定义。

与旧版VB比较

与旧版VB(VB 6.0及以前)相比较,VB.NET明显受到了.Net Framework中其他语言思想的影响。与旧版VB相比,VB.NET更加严格而不失灵活。

  • Long 类型与 Integer 类型的长度分别倍增,达到了64位和32位。
  • 事件的处理过程不再依赖于名称,而是通过 Handle 子句进行静态绑定或者在运行时进行动态绑定。例如处理按钮控件 Button1 的 Click 事件:

Visual Basic 6:(注意此过程的名称不可改变)

Private Sub Button1_Click()
    'Work to do
End Sub

VB.NET:(注意此过程的名称无关紧要)

Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handle Button1.Click
    'Work to do
End Sub
  • 很多原有的实现特殊功能的语句被相应定义好的函数替代。这减少了关键字的使用(如 Open() 函数取代 Open 语句,窗体的 Print() 方法取代 Print 语句)。同时,被封装好的、功能更强大的、通用于.Net Framework框架的类被推荐用来取代原有的语句。
  • 对一些更强大的语法特性的支持,如:LINQ,Lambda表达式(Visual Basic 2010起支持多行Lambda)。
  • 同样使用 作为一行中分行的符号, 作为续行符。但是VB.NET自Visual Basic 2012起允许在函数的定义与调用中不加 地用换行分隔各个参数。

与C#等C家族语言比较

与C家族语言相比,VB.NET则较多保留了VB的特征,比如:

  • 与C家族语言统一使用 、 定义语句块不同,VB.NET每种语句块都有对应的开头与结尾。如 If ... Else ... End If , Class ... End Class 
  • VB.NET定义变量使用 Dim 关键字,同时使用 Public 、 Private 或 Protected 表明作用域时可以省略 Dim 
  • VB.NET表示变量类型的方式是在变量名后附加 As Type (Type为变量类型),而C家族语言是在变量名之前书写类型名,无论在定义变量时还是在函数与形参的声明时都是这样。
  • VB.NET中有没有返回值的特殊子过程 Sub 。VB.NET中没有 void 类型,C#中返回值为 void 的函数对应了VB.NET中的 Sub 
  • VB.NET中有一种特殊的类型 Module ,相当于C#中的 static class 

下面这两份功能一致的代码展现出了VB.NET与C#的很多不同之处:

  • Visual Basic:
Namespace N
	'Comment
	Module M
		Public Function GetSum(arr() As Integer) As Integer
			Dim Sum = 0 'Auto Type Infer
			Dim i As Integer
			
			For Each i In arr
				Sum += i
			Next
			
			Return Sum
		End Function
	End Module
	
	Class C
		Private v As Integer
	
		Public Function F() As Integer
			Return v * v
		End Function
		
		Public Sub S(value As Integer)
			Me.v = value
		End Sub
		
		Public Sub New() 'Constructor
			Me.v = 0
		End Sub
	End Class

End Namespace
  • C#:
namespace N
{
	//Comment
	static class M
	{
		int GetSum(int[] arr)
		{
			var Sum = 0;
			int i;
			
			foreach(i in arr)
			{
				Sum += i;
			}
			
			return i;
		}
	};
	
	class C
	{
	private:
		int v;
	public:
		int F()
		{
			return v * v;
		}
		
		void S(int value)
		{
			this.v = value;
		}
		
		C() //Constructor
		{
			this.v = 0;
		}
	};
}

VB.NET与C#同为.Net Framework的两大主力程序设计语言,尽管有着各种各样的不同,两者最终都编译为MSIL并由CLR运行。两者功能基本一致,并可以在.Net Framework框架下方便地互相调用与协同开发。关于两者的优劣一直见仁见智。

历史

2002年Visual Basic .NET(VB 7.0)

Visual Basic .NET(VB 7.0)是随Visual C#和ASP.NET一起在2002年发布的最初始的VB.NET版本。C#被大力宣传为微软对付JAVA的王牌,受到媒体极力关注。然而VB.NET(有时被称为VB 7.0)影响面不广,这导致VB社区之外很少人关注它。那些试用过此版VB.NET的人在层层幕布下发现一个强大却艰深的语言,而且还有不少缺点,例如它的运行阶段组件(Run-Time)比VB6大了十倍,存储器使用量也大大增加。

VB 7.0引起了广泛的争议,主要原因在于对旧版VB的改动过大。许多资深的VB程序员抱怨VB.NET,因为VB.NET 2002丢掉了许多不再发行的VB6中使用的大量语言结构和用户界面功能,并且对保留下来的东西也改变了语意。例如,在VB.NET参数默认是以值方式传递的,而不是以引用方式。VB.NET 2002被半嘲讽半认真地称为Visual Fred或VB DOTNOT。作为对2005-03-08微软拒绝为VB6再提供维护与支持的回应,当月月底出现了反对者的请愿。

VB.NET的支持者们认为新语言在很多方面比旧版本更为强大,比如它以相比早期版本更为自然、紧密和完全的方式地加入了现代面向对象的编程范式。反对者们有不同意见,虽然VB6对对象模型支持有缺点,但是二次开发升级到VB.NET的成本比升级后的收益要高得多。而开发软件发布因特网版本的独立程序员也对VB.NET的RunTime尺寸过大不满。

针对开发者的不满,微软主要做了如下努力:使新的开发更容易启动,而把已开发的VB6代码升级到VB.NET。例子主要包括:完成VB6中的常见任务如打印预览;集成VB6和VB.NET解决方案(dubbed VB Fusion),从VB6代码转换到VB.NET。

微软在后续版本中撤销了一些过激的更改,并且吸取了经验。在以后版本中,语法的更改变得更加谨慎。

2003年Visual Basic .NET 2003(VB 7.1)

Visual Basic .NET 2003(VB 7.1)和.NET Framework 1.1一起发布。新功能包括对.NET Compact Framework的支持和更好的VB升迁向导。并改进了运行状况,IDE稳定性(尤其是后台编译器),以及运行时RunTime稳定性。另外,VB.NET 2003还有一个学院版Visual Studio .NET 2003 Academic Edition(VS03AE),它是分发给各国某些学者免费使用的版本。

2005年Visual Basic 2005(VB 8.0)

Visual Basic 2005(VB 8.0)是VB.Net的重大转变,微软决意在其软件名称中去掉了.NET部分。在VB2005中,微软增加了许多新功能,以引用VB对于初学者来说的一些优点:

主要的变动:

  • 不再支持“Edit and Continue” – 早期Visual Basic可以在调试时修改代码并且不经重新编译地执行。Visual Basic 2005去掉了这个功能;
  • 设计时表达式求值;
  • 提供My伪命名空间,包含了不需大量编码而访问特定.NET Framework功能的简单方式;提供了改进的VB到VB.NET转换向导;Using语法,简化了需要部署pattern to free resources的对象的使用;My编码,可隐藏由VB.NET IDE写的模板代码;数据源绑定,简化了数据库C/S开发。上述功能(尤其是My)增强了VB.Net成为快速开发应用平台的可能,并与C#进一步区别开来。Visual Basic 2005通过增加新功能而减小了和其它所谓更强大的.NET语言的差距。
  • 增加了.NET 2.0语言功能包括:泛型(generics)和Partial类(在一个文件里定义一个类的某部分然后在另外的文件里添加更多的定义,这个方法在集成用户书写的代码和系统自动生成的代码时尤其有用);
  • XML注释,可以被NDoc等工具处理而自动生成文档;
  • 操作符重载;
  • 支持在其它语言中已经广泛使用的unsigned integer数据类型;
  • 支持在许多C派生编程语言已提供的复合操作符如:”+=”, “-=”;
  • IsNot专利:If Not X Is Y表达式被转换成If X IsNot Y。当微软为IsNot申请专利时招致了恶名(尤其来自Real公司);
  • Visual Basic 2005 Express:作为VS产品线上的一部分,VB2005 Express是专为业余爱好者和新手定制的免费的VS Express系列的一员。Express版本目的定位在帮助人们学习一种语言,所以他们有和标准版一致的用户界面,只是少了一些高级功能。另外,VS Express版包括了VB6.0转换器,提供了从VB老版本升级的可行方法。

2008年Visual Basic 2008(VB 9.0)

Visual Basic 2008(VB 9.0)于2007年11月9日与Microsoft .NET Framework 3.5一起发布。

在VB2008中,微软增加了许多功能,包括:

  • IIF函数
  • 匿名类型
  • 支持LINQ
  • Lambda表达式
  • XML数据结构
  • 类接口

2010年Visual Basic 2010(VB 10.0)

Visual Basic 2010于2010年4月发布。

2012年Visual Basic 2012(VB 11.0)

2013年Visual Basic 2013(VB 12.0)

2015年Visual Basic 2015(VB 14.0)

Visual Basic 2015(VB 14.0)于2015年7月20日发布。

参考数据

参见

Visual Basic Visual Studio C#

外部链接

官方网站

教程

其他