Microsoft 使用这些指南开发示例和文档。 Visual Basic 语言规范并未定义编码标准。
编码约定令代码外观一致,使读者可以将注意力集中在内容而非布局上。
约定能够使读者更快速地理解代码,因为他们可以根据以前的经验作出假设。
约定使复制、更改和维护代码变得更加简单。
约定演示了 Visual Basic 的“最佳做法”。
讨论
命名约定
命名指南在 类库开发的设计准则 中介绍。
您无需为了符合指南而更改由 Visual Studio 设计器工具创建的对象的名称。
使用命名空间限定,而不添加 Imports 语句。 如果在默认情况下将命名空间导入到项目中,则无需完全限定此代码,因为在复制和粘贴此代码时,它将与 IntelliSense 一起以非限定形式运行。 要将长的代码行换行以便于阅读时,可以在“.”后面使限定名换行。例如:
Dim collection As System.Diagnostics. InstanceDataCollectionCollection请不要在变量名中使用“My”或“my”。 这样会与 My 对象混淆。
布局约定
好的布局通过设置格式,强调代码的结构并使代码更易于阅读。
通过整齐排列功能,用默认设置(智能缩进、4 字符缩进、将制表符保存为空格)对代码的格式进行设置。 有关更多信息,请参见“选项”对话框 ->“文本编辑器”->“Basic”->“VB 专用”。
每行仅使用一个语句。 请不要使用 Visual Basic line 行继续符 (:)。
每行仅使用一个声明。
如果整齐排列功能没有设置继续行的格式,则会将连续行缩进一个制表位。
在方法和属性定义之间添加至少一个空白行。
注释约定
不要在代码行的结尾处使用注释。 将注释放在单独行。
注释文本以大写字母开头。
注释以句点结束。
在注释分隔符 (') 和注释文本之间插入一个空格。
' Here is a comment.请勿创建已设置格式的将注释包含在内的星号块。
程序结构
在使用 Main 方法时,对新的控制台应用程序使用默认结构,对命令行参数使用 My。
Sub Main() For Each argument As String In My.Application.CommandLineArgs ' Add code here to use the string variable. Next End Sub
语言指南
String 数据类型
使用 & 来连接字符串:
MsgBox("hello" & vbCrLf & "goodbye")若要将字符串追加到循环,请使用 StringBuilder 对象:
Dim longString As New System.Text.StringBuilder For count As Integer = 1 To 1000 longString.Append(count) Next
类型推断
对于局部变量利用类型推断:
Public Sub GetQuery()
Dim filterValue = "London"
Dim query = From customer In customers
Where customer.Country = filterValue
End Sub
事件处理程序中的宽松委托
如果未在代码中使用事件参数,请使用宽松委托并省略事件参数:
Public Sub Form1_Load() Handles Form1.Load
End Sub
无符号数据类型
- 使用 Integer 而不是无符号类型,除非内存不足。
数组
初始化声明行上的数组时,请使用短语法:
Dim letters1() As String = {"a", "b", "c"}而不是:
Dim letters2() As String = New String() {"a", "b", "c"}将数组指定符置于变量上而不是类型上:
Dim letters3() As String = {"a", "b", "c"}而不是:
Dim letters4 As String() = {"a", "b", "c"}声明和初始化基本数据类型的数组时,使用 { } 语法:
Dim letters5() As String = {"a", "b", "c"}而不是:
Dim letters6(2) As String letters6(0) = "a" letters6(1) = "b" letters6(2) = "c"
使用 With 关键字
在针对一个对象执行一系列调用时,请考虑使用 With 关键字:
With orderLog
.Log = "Application"
.Source = "Application Name"
.MachineName = "Computer Name"
End With
在 For 或 For Each 语句中对循环变量使用类型推断
使类型推断可以确定循环范围变量的类型。
下面的示例演示了在 For 语句中使用类型推断:
For count = 0 To 2
MsgBox(names(count))
Next
下面的示例演示了在 For Each 语句中使用类型推断:
For Each name In names
MsgBox(name)
Next
使用 Try...Catch 和 Using 语句处理异常
不要使用 On Error Goto。
若要处理异常,请使用 Try...Catch 语句:
Dim conn As New SqlConnection("connection string") Try Conn.Open() Catch ex As SqlException Finally Conn.Close() End TryUsing 语句将 Try...Catch 语句与 Dispose 方法调用合并在一起,简化了代码。 如果使用的是 Try...Catch 语句,且 Finally 块中的唯一代码为对 Dispose 方法的调用,请改用 Using 语句:
Using redPen As New Pen(color.Red) ' Insert code here. End Using
使用 IsNot 关键字
优先使用 IsNot 关键字,而不是 Not...Is Nothing。
使用 AndAlso 和 OrElse 关键字
若要跳过不必要的代码来避免出现异常和提高性能,请在执行比较时使用 AndAlso(而不是 And)和 OrElse(而不是 Or):
' Avoid a null reference exception. If the left side of the AndAlso
' operator is False, the right side is not evaluated and a null
' exception is not thrown.
If nullableObject IsNot Nothing AndAlso nullableObject = testValue Then
End If
' Avoid an unnecessary resource-intensive operation. If the left side
' of the OrElse operator is True, the right side is not evaluated and
' a resource-intensive operation is not called.
If testCondition OrElse ResourceIntensiveOperation() Then
End If
窗体的默认实例
使用 Form1.ShowDialog 而不是 My.Forms.Form1.ShowDialog。
New 关键字
使用短实例化:
Dim employees As New List(Of String)下行与上行等效:
Dim employees2 As List(Of String) = New List(Of String)对于新对象使用对象初始值设定项,而不使用无参数的构造函数:
Dim orderLog As New EventLog With { .Log = "Application", .Source = "Application Name", .MachineName = "Computer Name"}
事件处理
使用 Handles 而不是 AddHandler:
Private Sub ToolStripMenuItem1_Click() Handles ToolStripMenuItem1.Click End Sub使用 AddressOf,且不要显式实例化此委托:
Dim closeItem As New ToolStripMenuItem( "Close", Nothing, AddressOf ToolStripMenuItem1_Click) Me.MainMenuStrip.Items.Add(closeItem)定义事件时,使用短语法并让编译器定义此委托:
Public Event WhatHappened(ByVal source As Object, ByVal e As WhatHappenedEventArgs)在调用 RaiseEvent 方法之前不检查事件是否为 Nothing (null)。 RaiseEvent 会在引发事件之前检查是否存在 Nothing。
使用共享成员
使用类名称调用 Shared 成员,而不是从实例变量调用。
使用 MsgBox 函数
使用 MsgBox,而非 MessageBox.Show 或 Console.WriteLine。 在不支持 MsgBox 函数的环境(如 Silverlight)中,请使用相应的替代项。
使用 My 命名空间
优先使用 My 功能,而不是 .NET Framework 类库或 Visual Basic 运行库。 有关更多信息,请参见对象 (Visual Basic)。
使用 XML 文本
XML 文本简化了处理 XML 时的最常规任务,例如,加载、查询和转换。 在使用 XML 进行开发时,请遵循下列准则:
使用 XML 文本创建 XML 文档和片段,而不直接调用 XML API。
在文件或项目级别导入 XML 命名空间,以利用 XML 文本的性能优化。
使用 XML 轴属性访问 XML 文档中的元素和特性。
使用嵌入表达式包括值并根据现有的值创建 XML,而不是使用 API 调用(如 Add 方法):
Private Function GetHtmlDocument( ByVal items As IEnumerable(Of XElement)) As String Dim htmlDoc = <html> <body> <table border="0" cellspacing="2"> <%= From item In items Select <tr> <td style="width:480"> <%= item.<title>.Value %> </td> <td><%= item.<pubDate>.Value %></td> </tr> %> </table> </body> </html> Return htmlDoc.ToString() End Function
LINQ 查询
对于查询变量使用有意义的名称:
Dim seattleCustomers = From cust In customers Where cust.City = "Seattle"为查询中的元素起别名,确保匿名类型的属性名称使用正确的 Pascal 大小写:
Dim customerOrders = From customer In customers Join order In orders On customer.CustomerID Equals order.CustomerID Select Customer = customer, Order = order在结果中的属性名称不明确时重命名属性。 例如,如果查询返回一个客户姓名和一个订单 ID,而不是在结果中保留它们的 Name 和 ID 形式,请重命名它们:
Dim customerOrders2 = From cust In customers Join ord In orders On cust.CustomerID Equals ord.CustomerID Select CustomerName = cust.Name, OrderID = ord.ID使用类型推断来声明查询变量和范围变量:
Dim customerList = From cust In customers对齐 From 语句下面的查询子句:
Dim newyorkCustomers = From cust In customers Where cust.City = "New York" Select cust.LastName, cust.CompanyName在其他查询子句前面使用 Where 子句,确保后面的查询子句作用于一组经过简化和筛选的数据:
Dim newyorkCustomers2 = From cust In customers Where cust.City = "New York" Order By cust.LastName使用 Join 子句显式定义联接,而不是使用 Where 子句隐式定义联接:
Dim customerList2 = From cust In customers Join order In orders On cust.CustomerID Equals order.CustomerID Select cust, order
使用 Visual Basic 运行库成员
优先使用 Visual Basic 运行库,而不是 .NET Framework 类库。