Visual Basic .NET

语法特性

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

数组

Dim arr([upperLimit]) As dataType = new dataType([upperLimit]) {[initialValues]} '声明数组arr(index) = value   '使用数组
数组的下标开始自0，这遵从了.NET的标准。如果不指定数组的下标上界，则为动态数组，其长度可以动态调整。

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 SubEnd 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
<Extension()> Public Function funcName(ByVal ins As className) As String
    'Do something
End Function

异常处理

Try
   ' write the condition hereCatch ex As Exception When condition
   ' Handle Exception when a specific condition is trueCatch ex As Exception
   ' Handle ExceptionFinally
   ' 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 SubEnd 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的定义。

调用C语言函数的规范

C语言编写的DLL文件，VB在调用时，需要注意：对于C语言的数组指针，在VB中调用时应将数组的首元素传递给DLL。不能直接传递数组名,因为如果传递数组名,VB实际会传一个复杂的结构类型给DLL。C函数无法确定数组大小，通常用另一个参数指出数组的大小。
<DllImport("D:\GenericMESDLL.dll", CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Cdecl)>Public Sub test(ByVal param As Integer, ByRef OK As Integer)End Sub'下述方法只能使用_stdcall调用约定：Public Declare Function test1 Lib "D:\PackingDLL.dll" Alias "_test@4" (ByVal param As Integer) As Integer

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年3月8日微软拒绝为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.0）

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

2010年Visual Basic 2010（VB 10.0）

Visual Basic 2010于2010年4月发布。

2015年Visual Basic 2015（VB 14.0）

Visual Basic 2015（VB 14.0）于2015年7月20日发布。