共用方式為


Visual Basic 的新功能

本文列出每個 Visual Basic 版本的主要功能名稱,並詳細描述最新版語言中的新功能和增強功能。

目前版本

Visual Basic 16.9 / Visual Studio 2019 16.9 版
如需新功能,請參閱 Visual Basic 16.9

您可以從 .NET 下載頁面下載最新的 .NET SDK。

舊版

Visual Basic 16.0 / Visual Studio 2019 16.0 版
如需新功能,請參閱 Visual Basic 16.0

Visual Basic 15.5 / Visual Studio 2017 15.5 版
如需新功能,請參閱 Visual Basic 15.5

Visual Basic 15.3 / Visual Studio 2017 15.3 版
如需新功能,請參閱 Visual Basic 15.3

Visual Basic 15 / Visual Studio 2017
如需新功能,請參閱 Visual Basic 2017

Visual Basic / Visual Studio 2015
如需新功能,請參閱 Visual Basic 14

Visual Basic / Visual Studio 2013
.NET 編譯器平臺 (“Roslyn”) 的技術預覽

Visual Basic / Visual Studio 2012
Asyncawait 關鍵字、疊代器、呼叫者資訊屬性

Visual Basic、Visual Studio 2010
自動實作的屬性、集合初始化程式、隱含行延續、動態、泛型 co/contra 變異數、全域命名空間存取

Visual Basic / Visual Studio 2008
語言整合查詢 (LINQ)、XML 常值、本機類型推斷、物件初始化設定式、匿名類型、延伸模組方法、本機 var 類型推斷、Lambda 運算式、 if 運算子、部分方法、可為 Null 的值類型

Visual Basic / Visual Studio 2005
My類型和協助程式類型 (存取應用程式、電腦、檔案系統、網路)

Visual Basic / Visual Studio .NET 2003
位移運算子、迴圈變數宣告

Visual Basic / Visual Studio .NET 2002
Visual Basic .NET 的第一個版本

Visual Basic 16.9

Visual Basic 16.9 允許使用僅限初始化的屬性。

Visual Basic 16.0

Visual Basic 16.0 著重於向 .NET Core 提供 Visual Basic 執行階段 (microsoft.visualbasic.dll) 的更多功能,並且是第一個專注於 .NET Core 的 Visual Basic 版本。 相依於 WinForms 的 Visual Basic 執行階段部分已新增至 .NET Core 3.0 中。

陳述式內允許在更多位置發表註解

在 Visual Basic 15.5 和更早版本中,只允許在空白行、陳述式結尾或陳述式內允許隱含行延續的特定位置使用註解。 從 Visual Basic 16.0 開始,也允許在明確的行接續之後,以及以空格後接底線開頭的行的陳述式內使用註解。

Public Sub Main()
    cmd.CommandText = ' Comment is allowed here without _
        "SELECT * FROM Titles JOIN Publishers " _ ' This is a comment
        & "ON Publishers.PubId = Titles.PubID " _
 _ ' This is a comment on a line without code
        & "WHERE Publishers.State = 'CA'"
End Sub

優化浮點到整數的轉換

在舊版的 Visual Basic 中,將 DoubleSingle 值轉換為整數的效能相對較差。 當您將下列任何方法傳回的值傳遞至其中一個 內建的 Visual Basic 整數轉換函式 (CByte、CShort、CInt、CLng、CSByte、CUShort、CUInt、CULng) 時,或當 Option Strict 設定為 Off

此最佳化可讓程式碼執行得更快,對於執行大量整數類型的程式碼,速度最高可達兩倍。 下列範例說明一些受此最佳化影響的簡單方法呼叫:

Dim s As Single = 173.7619
Dim d As Double = s

Dim i1 As Integer = CInt(Fix(s))               ' Result: 173
Dim b1 As Byte = CByte(Int(d))                 ' Result: 173
Dim s1 AS Short = CShort(Math.Truncate(s))     ' Result: 173
Dim i2 As Integer = CInt(Math.Ceiling(d))      ' Result: 174
Dim i3 As Integer = CInt(Math.Round(s))        ' Result: 174

請注意,這會截斷而不是四捨五入浮點值。

Visual Basic 15.5

非尾端具名引數

在 Visual Basic 15.3 和更早版本中,當方法呼叫同時包含依位置和名稱的引數時,位置引數必須位於具名引數之前。 從 Visual Basic 15.5 開始,只要最後一個位置引數之前的所有引數都位於正確的位置,位置引數和具名引數就可以以任何順序出現。 當使用命名參數使程式碼更具可讀性時,這特別有用。

例如,下列方法呼叫在具名引數之間有兩個位置引數。 具名引數清楚指出值 19 代表年齡。

StudentInfo.Display("Mary", age:=19, #9/21/1998#)

Private Protected 成員存取修飾符

這個新的關鍵字組合會定義一個成員,該成員可由其包含類別中的所有成員以及衍生自包含類別的類型存取,但前提是在包含元件中找到它們時。 因為結構無法繼承, Private Protected 所以只能套用到類別的成員。

領先的十六進制/二進制/八進制分隔符

Visual Basic 2017 新增了對底線字元 (_) 作為數字分隔符號的支援。 從 Visual Basic 15.5 開始,您可以使用底線字元作為前置詞與十六進位、二進位或八進位數字之間的前導分隔符號。 下列範例使用前導數字分隔符號將 3,271,948,384 定義為十六進位數:

Dim number As Integer = &H_C305_F860

若要使用底線字元做為前導分隔符號,您必須將下列元素新增至 Visual Basic 專案 (*.vbproj) 檔案:

<PropertyGroup>
  <LangVersion>15.5</LangVersion>
</PropertyGroup>

Visual Basic 15.3

命名元組推斷

當您從變數指派元組元素的值時,Visual Basic 會從對應的變數名稱推斷元組元素的名稱;您不需要明確命名元組元素。 下列範例會使用推論來建立具有三個命名元素 state、 和 stateNamecapital的元組。

Const state As String = "MI"
Const stateName As String = "Michigan"
Const capital As String = "Lansing"
Dim stateInfo = (state, stateName, capital)
Console.WriteLine($"{stateInfo.stateName}: 2-letter code: {stateInfo.State}, Capital {stateInfo.capital}")
' The example displays the following output:
'      Michigan: 2-letter code: MI, Capital Lansing

其他編譯器參數

Visual Basic 命令列編譯器現在支援 -refout-refonly 編譯器選項,以控制參考元件的輸出。 -refout 定義參照組件的輸出目錄,而 -refonly 指定僅透過編譯輸出參照組件。

Visual Basic 15

元組

元組是一種輕量級資料結構,最常用於從單一方法呼叫傳回多個值。 通常,若要從方法傳回多個值,您必須執行下列其中一項:

  • 定義自訂類型 (a ClassStructurea )。 這是一個重量級的解決方案。

  • 除了從方法傳回值之外,還定義一或多個 ByRef 參數。

Visual Basic 對元組的支援可讓您快速定義元組、選擇性地將語意名稱指派給其值,以及快速擷取其值。 下列範例會包裝方法的 TryParse 呼叫,並傳回元組。

Imports System.Globalization

Public Module NumericLibrary
    Public Function ParseInteger(value As String) As (Success As Boolean, Number As Integer)
        Dim number As Integer
        Return (Integer.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, number), number)
    End Function
End Module

然後,您可以呼叫方法,並使用如下程式碼處理傳回的元組。

Dim numericString As String = "123,456"
Dim result = ParseInteger(numericString)
Console.WriteLine($"{If(result.Success, $"Success: {result.Number:N0}", "Failure")}")
Console.ReadLine()
'      Output: Success: 123,456

二進位文字和數字分隔符號

您可以使用字首 &B&b來定義二進位文字。 此外,您可以使用底線字元 _作為數字分隔符號,以增強可讀性。 下列範例會使用這兩個功能來指派 Byte 值,並將其顯示為十進位、十六進位和二進位數。

Dim value As Byte = &B0110_1110
Console.WriteLine($"{NameOf(value)}  = {value} (hex: 0x{value:X2}) " +
                  $"(binary: {Convert.ToString(value, 2)})")
' The example displays the following output:
'      value  = 110 (hex: 0x6E) (binary: 1101110)      

如需詳細資訊,請參閱 ByteIntegerLongShortSByteUIntegerULongUShort 資料類型的「常值指派」一節。

支援 C# 參考傳回值

C# 支援參考傳回值。 也就是說,當呼叫方法收到引用傳回的值時,它可以改變引用的值。 Visual Basic 不允許您使用參考傳回值撰寫方法,但它允許您取用和修改參考傳回值。

例如,下列 Sentence 以 C# 撰寫的類別包含一個 FindNext 方法,可在以指定子字串開頭的句子中尋找下一個單字。 字串會傳回為參考傳回值, Boolean 而參考方法傳遞的變數會指出搜尋是否成功。 這意味著呼叫者除了讀取傳回值之外,還可以對其進行修改,並且該修改會反映在類別中 Sentence

using System;

public class Sentence
{
    private string[] words;
    private int currentSearchPointer;

    public Sentence(string sentence)
    {
        words = sentence.Split(' ');
        currentSearchPointer = -1;
    }

    public ref string FindNext(string startWithString, ref bool found)
    {
        for (int count = currentSearchPointer + 1; count < words.Length; count++)
        {
            if (words[count].StartsWith(startWithString))
            {
                currentSearchPointer = count;
                found = true;
                return ref words[currentSearchPointer];
            }
        }
        currentSearchPointer = -1;
        found = false;
        return ref words[0];
    }

    public string GetSentence()
    {
        string stringToReturn = null;
        foreach (var word in words)
            stringToReturn += $"{word} ";

        return stringToReturn.Trim();
    }
}

在最簡單的形式中,您可以使用如下程式碼來修改句子中找到的單字。 請注意,您不是將值指派給方法,而是指派給方法傳回的運算式,也就是參考傳回值。

Dim sentence As New Sentence("A time to see the world is now.")
Dim found = False
sentence.FindNext("A", found) = "A good" 
Console.WriteLine(sentence.GetSentence()) 
' The example displays the following output:
'      A good time to see the world is now.

不過,此程式碼的一個問題是,如果找不到相符項,該方法會傳回第一個單字。 由於範例不會檢查引數的 Boolean 值來判斷是否找到相符項目,因此如果沒有相符項目,它會修改第一個單字。 下列範例會以 [沒有相符專案] 取代第一個字組,以本身取代來修正此問題。

Dim sentence As New Sentence("A time to see the world is now.")
Dim found = False
sentence.FindNext("A", found) = IIf(found, "A good", sentence.FindNext("B", found)) 
Console.WriteLine(sentence.GetSentence()) 
' The example displays the following output:
'      A good time to see the world is now.

更好的解決方案是使用協助程式方法,其中參考傳回值會透過引用傳遞給該方法。 然後,協助程式方法可以修改透過引用傳遞給它的引數。 下列範例會執行此動作。

Module Example
   Public Sub Main()
      Dim sentence As New Sentence("A time to see the world is now.")
      Dim found = False
      Dim returns = RefHelper(sentence.FindNext("A", found), "A good", found) 
      Console.WriteLine(sentence.GetSentence()) 
   End Sub
   
   Private Function RefHelper(ByRef stringFound As String, replacement As String, success As Boolean) _ 
                    As (originalString As String, found As Boolean) 
      Dim originalString = stringFound
      If found Then stringFound = replacement
      Return (originalString, found)   
   End Function
End Module
' The example displays the following output:
'      A good time to see the world is now.

如需詳細資訊,請參閱 參考傳回值

Visual Basic 14

名稱

您可以取得類型或成員的非限定字串名稱,以用於錯誤訊息,而不需要硬式編碼字串。 這可讓您的程式碼在重構時保持正確。 此功能對於連接模型-視圖-控制器 MVC 連結和觸發屬性變更事件也很有用。

字串插補

您可以使用字串插補運算式來建構字串。 內插字串運算式看起來像包含運算式的範本字串。 內插字串在引數方面比 複合格式更容易理解。

Null 條件式成員存取和索引

在執行成員存取 (?.) 或索引 (?[]) 作業之前,您可以以非常輕的語法方式測試 Null。 這些運算子可協助您撰寫較少的程式碼來處理空值檢查,特別是對於遞減到資料結構。 如果左側運算元或物件參考為 Null,則作業會傳回 Null。

多行字串常值

字串常值可以包含換行序列。 您不再需要使用 <xml><![CDATA[...text with newlines...]]></xml>.Value

評論

您可以在隱含的行接續之後、初始化運算式內,以及 LINQ 運算式術語之間放置註解。

更智慧的完整名稱解析

假設 Visual Basic 用來查詢命名空間 “Threading” 的 Threading.Thread.Sleep(1000)程式碼,發現它在 System.Threading 和 System.Windows.Threading 之間不明確,然後回報錯誤。 Visual Basic 現在會同時考慮這兩個可能的命名空間。 如果您顯示完成清單,Visual Studio 編輯器會在完成清單中列出這兩種類型的成員。

年份第一個日期常值

您可以擁有 yyyy-mm-dd 格式 #2015-03-17 16:10 PM#的日期文字。

唯讀介面屬性

您可以使用 readwrite 屬性來實作唯讀介面屬性。 介面保證最低功能,而且不會阻止實作類別允許設定屬性。

TypeOf <expr> IsNot <類型>

為了提高程式碼的可讀性,您現在可以搭配 TypeOf 使用 IsNot

#Disable 警告 <ID> 和 #Enable 警告 <ID>

您可以停用和啟用來源檔案內區域的特定警告。

XML 文件註解改善

編寫文檔註釋時,您可以獲得智能編輯器並構建支持驗證參數名稱、正確處理 crefs (泛型、運算子等)、著色和重構。

部分模組和介面定義

除了類別和結構之外,您還可以宣告部分模組和介面。

#Region 方法主體內的指令

您可以將 #Region...#End 區域分隔符號放在檔案中的任何位置、函數內部,甚至跨函數主體。

覆寫定義是隱含的重載

如果您將修飾元新增至 Overrides 定義,編譯器會隱含地新增 Overloads ,以便在常見情況下輸入較少的程式碼。

屬性引數中允許的 CObj

編譯器過去常常給出錯誤,即在屬性建構中使用時 CObj(...) 不是常數。

宣告和使用來自不同介面的模棱兩可的方法

先前,下列程式碼會產生錯誤,導致您無法宣告 IMock 或呼叫 GetDetails (如果這些錯誤已在 C# 中宣告):

Interface ICustomer
  Sub GetDetails(x As Integer)
End Interface

Interface ITime
  Sub GetDetails(x As String)
End Interface

Interface IMock : Inherits ICustomer, ITime
  Overloads Sub GetDetails(x As Char)
End Interface

Interface IMock2 : Inherits ICustomer, ITime
End Interface

現在,編譯器會使用一般多載解析規則來選擇最適當的 GetDetails 呼叫,而且您可以在 Visual Basic 中宣告介面關聯性,如範例中所示。

另請參閱