Visual Basic 编码约定
更新: 2008 年 7 月
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 Try
Using 语句将 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 轴属性 (Property) 访问 XML 文档中的元素和属性 (Attribute)。
使用嵌入表达式包括值并根据现有的值创建 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" _ Select cust.LastName, cust.CompanyName
使用 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 类库。
示例指南
通用
遵循 Design Guidelines for Class Library Developers(类库开发人员设计指南)中的设计指南。
指定 MsgBox 调用的提示和标题。
在适当时使用资源文件。
在每个文件中使用 Option Strict On,或将其用作项目设置。
在编译时打开所有警告。
在一个文件中仅定义一个 Class、Structure 或 Interface。
使用默认编码保存文件。
本地化
在可能的地方使用 AutoSize 属性。
不要隐藏或重叠控件。
不要排列控件以创建语句。
不要通过从另一字符串抽出字符来生成字符串。
使用非特定区域性的图形。
仅使用 Tahoma 或 MS Sans Serif 字体。
辅助功能
使用颜色选取器对话框的“系统”选项卡中的颜色。
为所有菜单、标签和按钮等使用快捷键。
按照下表中的描述设置控件属性。
属性 |
设置 |
---|---|
AccessibleDescription |
控件的描述。 |
AccessibleName |
控件名称。 |
AccessibleRole |
默认值,如果控件有另一角色,则重置该属性。 |
TabIndex |
按逻辑顺序设置。 |
Text |
所有可单击的控件都应有一个键盘访问键(快捷键)。 |
Font size |
默认值,或设置为 10 磅或以上 |
Forecolor |
默认值 |
Backcolor |
默认值 |
BackgroundImage |
默认值 |
安全性
遵循代码安全维护指南中的指南。
请参见
其他资源
修订记录
日期 |
历史记录 |
原因 |
---|---|---|
2008 年 7 月 |
更新了指南,现在包括新的语言功能,其中包括 LINQ、XML 文本、对象初始值设定项、类型推断和宽松委托。 |
内容 Bug 修复 |