Visual Basic 2017の新機能

# はじめに

これは、[Visual Basic Advent Calendar 2016](http://qiita.com/advent-calendar/2016/vb)の25日目の記事となります。

正式には現時点で「Visual Basic 2017」となることが発表されてなく、内部バージョンのVB15.0となっているですが、現在「Visual Studio 2017」の[リリース候補版がダウンロード](https://www.visualstudio.com/ja/vs/visual-studio-2017-rc/)されている状態であり、2017年に発売(3月7日に決定)されることと推定されるため、あえてこのタイトルとしました。

# VBの進化の歴史
新機能を紹介する前に、今までのVisual Basicの進化の歴史を整理してみます。

|製品名|リリース|内部バージョン|.NET Framework|変更点、備考|
|:---|:---|:---|:---|:---|
|Visual Basic 6.0|1998|6.0 |  |歴代VBの名作、未だに使われる|	
|Visual Basic .NET|2002|7.0|1.0|初めての.NET|
|Visual Basic .NET 2003|2003|7.1|1.1|安定してきた.NET|
|Visual Basic 2005|2005|8.0|2.0,(3.0)|[2005の新機能 - MSDN](https://msdn.microsoft.com/ja-jp/library/we86c8x2(v=vs.80).aspx)|
|Visual Basic 2008|2007|9.0|3.5,3.0,2.0|[2008の新機能 - MSDN](https://msdn.microsoft.com/ja-jp/library/y17w47af(v=vs.110).aspx)|
|Visual Basic 2010|2010|10.0|4.0|[2010の新機能 - MSDN](https://msdn.microsoft.com/ja-jp/library/we86c8x2(v=vs.100).aspx)|
|Visual Basic 2012|2012|11.0|4.5|[2012の新機能 - MSDN](https://msdn.microsoft.com/ja-jp/library/we86c8x2(v=vs.110).aspx?f=255&MSPPError=-2147217396)|
|Visual Basic 2013 |2013|12.0|4.5.1|内部変更のみと思われる|
|Visual Basic 2015|2015|14.0|4.6|[2015の新機能 - MSDN](https://msdn.microsoft.com/ja-jp/library/we86c8x2.aspx)|
|Visual Basic 2017|2017|15.0|4.6.1,4.6.2|[2017の新機能 - MSDN](https://www.visualstudio.com/en-us/news/releasenotes/vs2017-relnotes#cshappvb)|

※内部バージョン13.0は、[忌み番号のためスキップ](http://qiita.com/yaju/items/4353f621cff3bcc7ed72)されています。

## VB2005(VB8.0)の新機能
参照：[VS 2005で新しくなったVisual BasicとC#の新機能を総括](http://www.atmarkit.co.jp/fdotnet/special/vs2005_02/vs2005_02_01.html)

* 部分クラス（パーシャル・クラス）
* ジェネリック
* プロパティの個別アクセシビリティ・レベル定義
* My機能
* Usingステートメント
* フォームの既定インスタンス
* Globalキーワード
* 演算子のオーバーロード
* Continueステートメント
* XMLドキュメント・コメント

## VB2008(VB9.0)の新機能
参照：[Visual Basic 言語の新機能](https://msdn.microsoft.com/ja-jp/library/y17w47af(v=vs.90).aspx)、[VBの進化](http://rucio.cloudapp.net/ThreadDetail.aspx?ThreadId=11054)

* .NET Framework 2.0/3.0/3.5 に対応
* LINQ(統合言語クエリ)に対応
* Null 許容型に対応(「As Nullable(Of Integer)」を「As Integer?」と書ける)
* 型推論(「Dim a = 10」と書くと「Dim a As Integr = 10」の意味になる)
* オブジェクト初期化子(Dim a As New Point() With {.X = 10, .Y = 20})
* 匿名型(「Dim a = New With {.Name = "名無しのＶ", .Job = "社会人"}」)
* 拡張メソッドに対応(ExtensionAttribute 属性)
* ラムダ式に対応(「Dim ave = Function(x As Integer, y As Integer) (x + y) / 2」)
* XML リテラル、XML 軸プロパティ(「Dim a = <abc>xyz</abc>」)
* If 演算子の追加(三項演算子)…If ステートメントとIIf関数を合わせたような物
* 部分メソッド「Partial Private Sub」のサポート(VB2005 のPartial Classと併用する)

## VB2010(VB10.0)の新機能
参照：[Visual Basic 2010の新機能](http://www.atmarkit.co.jp/fdotnet/chushin/vb2010features_01/vb2010features_01_01.html)、[VBの進化](http://rucio.cloudapp.net/ThreadDetail.aspx?ThreadId=11054)

* 行継続文字「 _」を省略可能になった(分割位置によっては省略できない場合もある)
* コレクション初期化子に対応(「Dim a As New List(Of String)() From {"VB", "C#", "F#"}」)
* 自動実装プロパティ(End Property無しの「Public Property Name As String」)
* 複数行ラムダ式およびSub のラムダ式に対応
* 並列処理の追加  
　・Parallel.Forメソッド、Parallel.ForEachメソッド  
　・Taskクラス  
　・Parallel LINQ (AsParallelメソッド)
* VBランタイムの無効化オプション(/vbruntime オプション)
* 動的オブジェクトのサポート(System.Dynamic 名前空間)
* ジェネリックの共変性と反変性

## VB2012(VB11.0)の新機能
参照：[C#／VB言語の新機能](http://www.atmarkit.co.jp/fdotnet/special/vs2012review/vs2012review_04.html)

* Async / Await キーワードによる非同期コードサポート
* Iterator/Yield キーワードによる反復子
* 呼び出し階層
* メソッド情報
* Global Namespaceのサポート

## VB2013(VB12.0)の新機能
新機能の追加は一切ありません。(.NET Framework 4.5.1 に対応のみ)

## VB2015(VB14.0)の新機能
参照：[What's New for Visual Basic - MSDN](https://msdn.microsoft.com/ja-jp/library/we86c8x2.aspx)

* Nameof 演算子
* 文字列の補間
* Null 条件付きのメンバー アクセスとインデックス作成
* 複数行の文字列リテラル
* 複数行にまたがるステートメントに対するコメント
* スマートな完全修飾名前解決
* 年が最初にくる日付リテラル
* ReadOnly インターフェイスのプロパティ
* TypeOf <expr> IsNot <type>
* #Disable Warning <ID> と #Enable Warning <ID>
* XML ドキュメント コメントの機能強化
* 部分モジュールとインターフェイスの定義
* メソッド本体内の #Region ディレクティブ
* 上書きの定義は暗黙的オーバーロードです
* 属性の引数で使用できる CObj
* 異なるインターフェイスからのあいまいなメソッドの宣言と使用

## 備考
Visual Studio 2010以降からVisual Basic 6.0のアプリケーションをアップグレードする機能は組み込まれないようになりました。

[VB6からVS2013にアップグレードする方法](http://shinsuke789.hatenablog.jp/entry/2014/05/13/120211)
手順は「VB6→VS2008→VS2013」となります。
VS2008 Expressは次のサイト等で入手できます。
[NonSoft - Visual Studio 2008 Expressのダウンロードとインストール](http://nonsoft.la.coocan.jp/Chinamini/20110001/20110307.html)
[Visual Basic 6.0 ユーザーのための Visual Basic .NET 移行ガイド](https://msdn.microsoft.com/ja-jp/library/dd314356.aspx?f=255&MSPPError=-2147217396)
[Microsoft.VisualBasic.Compatibility.VB6 名前空間](https://msdn.microsoft.com/ja-jp/library/microsoft.visualbasic.compatibility.vb6(v=vs.110).aspx)は、.NET Framework Version 4以降Obsoleteとされるクラスである。

# VB2017(VB15.0)の新機能
【2017/04/06追記】
英語ですがMSDNにて下記ブログが書かれました。
[What’s New in Visual Basic 2017 - MSDN The Visual Basic Team](https://blogs.msdn.microsoft.com/vbteam/2017/03/30/whats-new-in-visual-basic-2017/)
[Visual Basic 15の新たな言語機能](https://www.infoq.com/jp/news/2017/05/VB-15)(MSDNの一部を日本語化)


## 2進数リテラル
これまで16進数リテラルは&H、8進数リテラルは＆Oとあったのですが、2進数リテラルはありませんでした。
MSX-BASICなどでは&Bで使えていたので、既にあるものと勘違いしてました。

```vbnet
Dim b1 As Byte = &B1111
Dim b2 As Byte = &B10101010
Dim s1 As Integer = &B1111000011110000
Console.WriteLine($"{b1:X}") 'F
Console.WriteLine($"{b2:X}") 'AA
Console.WriteLine($"{s1:X}") 'F0F0
```


## 数字区切り文字
' _ '(アンダースコア) を使って桁区切りが出来るようになりました。リテラルの桁数が大きい時に便利です。但し、末尾や先頭や小数点の前後には書けません。
※C#7.0と違い浮動小数点数(1.123_456_789)では使えないようです。

```vbnet
Dim s1 As Integer = &B1011_1100_1011_0011
Dim s2 As Integer = &B1_111_000_111_000_111
Dim x1 As Integer = &H44AA_ABCD
Dim million As Long = 1_000_000
Console.WriteLine($"{s1:X}") 'BCB3
Console.WriteLine($"{s2:X}") 'F1C7
Console.WriteLine($"{x1:X}") '44AAABCD
Console.WriteLine($"{million}") '1000000
```

## タプル
タプルは、異なる型を要素として扱い複合的なデータを表現することが出来ます。

VB2010 (.net 4.0) から Tuple 型が使えるようになっていました。(元々は F# で複数の値を戻すための実装)

```vbnet
Function func() As Tuple(Of String, Integer, Double)
    Return Tuple.Create("aaa", 1, 2.0)
End Function

Sub Main()
    Dim a = func()
    Console.WriteLine("{0} {1} {2}", a.Item1, a.Item2, a.Item3)
End Sub
```
VB2017からは、Tupleキーワードが不要となります。
※使用するには対象のフレームワークを「.NET Framework 4.7」にするか、Nugetから System.ValueTuple を導入する必要があります。(~~この制限は正式版ではなくなる予定~~→2017/03/09追記:正式版でも必要のまま)
参照：[VisualBasic .net 15 の新機能](http://qiita.com/Gnico/items/6dccb8475d22b05dc3c0)

```vbnet
Function func() As (s As String, x As Integer, y As Double)
    Return ("aaa", 1, 2.0)
End Function

Sub Main()
    Dim a = func()
    Console.WriteLine("{0} {1} {2}", a.Item1, a.Item2, a.Item3)
    '結果 "aaa", 1, 2.0
End Sub
```
[C# によるプログラミング入門   [データ型] タプル](http://ufcpp.net/study/csharp/datatype/tuples/)から一部だけVBに置き換えてみます。
**型の明示 - ジェネリックな型の型引数**

```vbnet
Dim dic = New Dictionary(Of (s As String, t As String), (x As Integer, y As Integer)) From
        {
            {("a", "b"), (1, 2)},
            {("x", "y"), (4, 8)}
        }

Console.WriteLine(dic(("a", "b"))) '(1,2)
```
## ByRef return
イマイチ理解出来てないです、参照した中国ブログではC#との連携っぽいことが書かれていました。

* [Visual Basic Language Design Meeting Notes - 2016.05.06](https://github.com/dotnet/roslyn/issues/11370)
*  [VS "15" 预览 5 中 VB 15 新增的功能](http://www.cnblogs.com/Nukepayload2/p/vs_15_pre5_vb_new.html)

【2017/04/06追記】MSDNの記事に詳しく書かれています。
参照：[What’s New in Visual Basic 2017 - MSDN The Visual Basic Team](https://blogs.msdn.microsoft.com/vbteam/2017/03/30/whats-new-in-visual-basic-2017/)

【2017/06/18追記】自分なりに調べて書いてみました。
[【Visual Basic】ByRef returnについて](http://qiita.com/yaju/items/728e96cf96601aebaa65)

# Visual Basic Language Design features
新機能の追加自体は今回少なかったですね。
VB2015の時に計画されていたが次のバージョンに持ち越した中で、2進数リテラルと数値区切りは、VB2017で採用されました。
他にもVisual Basicの言語デザインで将来計画されている内容を紹介します。採択されるかは不明です。
参照:[Languages features in C# 6 and VB 14](http://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status)

## Select Caseステートメントの拡張
数値や文字列だけであれば、今でもSelect Case文で問題ありません。しかし、型によるパターンマッチは今は出来ません。

```vbnet
Private Sub Button_Click(sender As Object, e As EventArgs) Handles OKButton.Click, CancelButton.Click

    Select Case sender
        Case Is OKButton
            DialogResult = DialogResult.OK
            Close()
        Case Is CancelButton
            DialogResult = DialogResult.Cancel
            Close()
        Case Is Nothing
            Throw New NullReferenceException("sender")
        Case Else
            Debug.Fail("Unknown sender.")
    End Select      
End Sub
```

## Dictonaryの初期化方法の追加(! operatorの追加)
! 演算子 (bang operator | 感嘆符演算子) を使ってItemの記述を省略したい。

```vbnet
Dim customer = New JsonData With { 
                   !First = "Lucian", ' .Item("First") = "Lucian" 
                   !Last = "Wischik"  ' .Item("Last") = "Wischik"
               }
```

## 暗黙的に定義される参照引数(Output キーワードの追加)
~~C#のOut修復子をVBでも採用したかったと思われる。 [C#のrefとoutの違い](http://dobon.net/vb/dotnet/beginner/byvalbyref.html)
(メソッド内でoutパラメータの値を使用することができず、必ずoutパラメータには新しい値を代入しなければなりません。)~~

【2017/07/01追記】
VBはメソッド内のすべてのローカル変数を自動的に初期化するのでC#のoutは不要。
ここで言いたいのは、戻り値(ByRef)を使うTryParse等では一時変数を別途用意する必要があるが、outputキーワードで一時変数を定義しなくても使えるようにしたかった。

```vbnet
' Callsite:
If Integer.TryParse(s, Output x) Then

' Declaration-site:
Function TryParse(s As String, Output x As Integer) As Boolean
```

## Catchブロック内でのAwaitキーワードのサポート
C#のみサポートされて、VBはサポートされませんでした。

```vbnet
Dim res As Resource = Nothing
Try
    res = Await Resource.OpenAsync(...)   ' You could do this.
Catch ex As ResourceException
    Await Resource.LogAsync(res, e)   ' Now you can do this ...
Finally
    If res IsNot Nothing Then Await res.CloseAsync() ' ... and this.
End Try
```

# 最後に
[Visual Basic Advent Calendar 2016](http://qiita.com/advent-calendar/2016/vb)の最後の記事でした。参加して頂いた皆様ありがとうございます。

C#は国際標準化機構 (ISO) によって標準化されているのに、Visual Basicはマイクロソフトの独自の言語ということもあって、歴史はあるけど人気はないですね。
UnityにはC#が採用されていますし、XamarinでもVB.NETは使えますが[PCL 内で記述までとの制限](http://ytabuchi.hatenablog.com/entry/2015/09/09/173455)があります。
※Xamarin iOSとAndroidプロジェクトは、Visual Basicをネイティブにサポートしていません。

Monoに関してもVisual Basic 8 = Visual Studio 2005 相当に留まっています。ただ、Linux環境においてはマイクロソフトのクロスプラットフォーム化によって、.NET CoreやRoslynがオープンソース化されていますので、ここはかなり改善される気がします。

これからもVisual Basicを暖かく見守っていきますので、来年もよろしくお願いします。

【2017/02/24追記】
InfoQの「[.NETの将来に関するMicrosoftの計画](https://www.infoq.com/jp/news/2017/02/strategic-net)」の記事によれば、将来の設計計画ではC#の設計からVBを切り離し、新しい開発者の.NETのファーストクラス言語としての位置付けとのこと。

【2018/08/02追記】
.NET Core 3では、3つの言語(C#, VB, F#) をサポートする。2018年後半にプレビュー公開、正式版は2019年リリース予定
https://www.infoq.com/jp/news/2018/05/net-core3-announced

Update on VBLang #322 にて、今後のVBについて議論がかわされています。
https://github.com/dotnet/vblang/issues/322

Features Added in VB Language Versions にて、VB15.xの機能追加が一覧化されています。
https://github.com/dotnet/vblang/blob/master/Language-Version-History.md