次の方法で共有


Visual Basic の新機能

この記事では、Visual Basic の各バージョンの主要な機能名と、最新バージョンの言語の新機能と強化された機能について詳しく説明します。

現在のバージョン

Visual Basic 16.9 / Visual Studio 2019 バージョン 16.9
新機能については、 Visual Basic 16.9 を参照してください。

最新の .NET SDK は 、.NET ダウンロード ページからダウンロードできます。

以前のバージョン

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
Asyncキーワード、反復子、呼び出し元情報属性のawait

Visual Basic、Visual Studio 2010
自動的に実装されるプロパティ、コレクション初期化子、暗黙的な行の継続、動的、ジェネリック co/contra variance、グローバル名前空間アクセス

Visual Basic / Visual Studio 2008
言語統合クエリ (LINQ)、XML リテラル、ローカル型推論、オブジェクト初期化子、匿名型、拡張メソッド、ローカル var 型推論、ラムダ式、 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 では、init のみのプロパティを使用できます。

Visual Basic 16.0

Visual Basic 16.0 では、Visual Basic ランタイム (microsoft.visualbasic.dll) の機能の多くを .NET Core に提供することに重点を置いています。これは、.NET Core に重点を置いた Visual Basic の最初のバージョンです。 .NET Core 3.0 では、WinForms に依存する Visual Basic ランタイムの部分が追加されました。

ステートメント内の他の場所で許可されるコメント

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 では、 Double 値と Single 値を整数に変換すると、パフォーマンスが比較的低下しました。 Visual Basic 16.0 では、次のいずれかのメソッドから返される値を 組み込みの Visual Basic 整数変換関数 (CByte、 CShort、CInt、CLng、CSByte、CUShort、CUInt、CULng)、または Option StrictOffに設定されている場合、次のいずれかのメソッドによって返される値が暗黙的に整数型にキャストされる場合。

この最適化により、整数型への多数の変換を行うコードの場合、コードの実行速度を最大で 2 倍速くできます。 次の例は、この最適化の影響を受けるいくつかの単純なメソッド呼び出しを示しています。

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 以降では、位置指定引数と名前付き引数は、最後の位置指定引数までのすべての引数が正しい位置にある限り、任意の順序で表示できます。 これは、コードをより読みやすくするために名前付き引数を使用する場合に特に便利です。

たとえば、次のメソッド呼び出しには、名前付き引数の間に 2 つの位置引数があります。 名前付き引数は、値 19 が年齢を表していることを明確にします。

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

Private Protected メンバー アクセス修飾子

この新しいキーワードの組み合わせは、その包含クラス内のすべてのメンバーと、包含クラスから派生した型によってアクセスできるメンバーを定義しますが、それが包含アセンブリ内に存在する場合にのみアクセスできます。 構造体は継承できないため、 Private Protected はクラスのメンバーにのみ適用できます。

先頭の 16 進数/バイナリ/8 進数の区切り記号

Visual Basic 2017 では、アンダースコア文字 (_) のサポートが桁区切り記号として追加されました。 Visual Basic 15.5 以降では、プレフィックスと 16 進数、バイナリ、または 8 進数の間の先頭の区切り記号としてアンダースコア文字を使用できます。 次の例では、先頭の桁区切り記号を使用して、3,271,948,384 を 16 進数として定義します。

Dim number As Integer = &H_C305_F860

先頭の区切り記号としてアンダースコア文字を使用するには、Visual Basic プロジェクト (*.vbproj) ファイルに次の要素を追加する必要があります。

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

Visual Basic 15.3

名前付きタプル推論

変数からタプル要素の値を割り当てると、Visual Basic は対応する変数名からタプル要素の名前を推論します。タプル要素に明示的に名前を付ける必要はありません。 次の例では、推論を使用して、 statestateName、および capitalの 3 つの名前付き要素を持つタプルを作成します。

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

タプルは、1 つのメソッド呼び出しから複数の値を返すために最も一般的に使用される軽量のデータ構造です。 通常、メソッドから複数の値を返すには、次のいずれかの操作を行う必要があります。

  • カスタム型 ( Class または Structure) を定義します。 これは重いソリューションです。

  • メソッドから値を返すだけでなく、1 つ以上の 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 値を割り当て、10 進数、16 進数、2 進数で表示します。

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 では、参照戻り値を使用してメソッドを作成することはできませんが、参照戻り値を使用して変更することができます。

たとえば、C# で記述された次の Sentence クラスには、指定した部分文字列で始まる文内の次の単語を検索する 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

NameOf

文字列をハード コーディングしなくても、エラー メッセージで使用する型またはメンバーの非修飾文字列名を取得できます。 これにより、リファクタリング時にコードを正しく維持できます。 この機能は、モデル ビュー コントローラー MVC リンクをフックし、プロパティ変更イベントを発生させるためにも役立ちます。

文字列補間

文字列補間式を使用して文字列を構築できます。 挿入文字列式は、式を含むテンプレート文字列のようになります。 挿入文字列は、 複合書式よりも引数に関して理解しやすくなります。

Null 条件付きメンバー アクセスとインデックス作成

メンバー アクセス (?.) またはインデックス (?[]) 操作を実行する前に、非常に軽い構文で null をテストできます。 これらの演算子を使用すると、特にデータ構造への降順の場合に、null チェックを処理するコードの記述が少なくなります。 左オペランドまたはオブジェクト参照が null の場合、操作は null を返します。

複数行の文字列リテラル

文字列リテラルには改行 シーケンスを含めることができます。 使用に関する古い回避策は不要になった <xml><![CDATA[...text with newlines...]]></xml>.Value

コメント

暗黙的な行連結の後、初期化子式内、および LINQ 式用語の間でコメントを配置できます。

よりスマートな完全修飾名前解決

Threading.Thread.Sleep(1000)などのコードを指定すると、Visual Basic は名前空間 "Threading" を検索し、System.Threading と System.Windows.Threading の間であいまいであったのを検出し、エラーを報告します。 Visual Basic では、両方の可能な名前空間が一緒に考慮されるようになりました。 完了リストを表示すると、Visual Studio エディターに両方の種類のメンバーが入力候補一覧に一覧表示されます。

年初の日付リテラル

日付リテラルは、yyyy-mm-dd 形式 ( #2015-03-17 16:10 PM#) で指定できます。

Readonly インターフェイスのプロパティ

readwrite プロパティを使用して、読み取り専用インターフェイス プロパティを実装できます。 このインターフェイスは最小限の機能を保証し、実装クラスがプロパティの設定を停止することはありません。

TypeOf <expr> IsNot <type>

コードを読みやすくするために、IsNotTypeOfを使用できるようになりました。

#Disable Warning <ID> および #Enable Warning <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 で宣言できます。

こちらも参照ください