VB14の新機能の確認したい

はじめに

ついに Visual Studio 2015 の正式版がリリースされましたね。

と、言うわけで VB14 の新機能を一通り確認したいと思います。

はい、そこ

やるんだったら CTP が出たタイミングでやれよ

とか

どーせ C# の後追いだろ

とか

似たような記事が○○(ここには任意のIT系の情報サイト名を入れる)にあったしどーせ『これで VB.NETC# と遜色の無い言語に仕上がりましたね(ニコッ』で締めるんだろ

とか言わないの。確かにそうだけど言わないの。

気付いたらリリースされてて慌ててインストールして確認作業をやったわけじゃないんです。 本当ですよ。 リリースの2日前にTwitterで呟かれているのに気付いてそこで初めてリリース日を確認したとかじゃ断じてありませんからね。

参照先

焦ってググったらこの辺がヒットしたんで、多分これを参照すればいいんじゃないかなーって感じでこれらを参照しました。

Languages features in C# 6 and VB 14 · dotnet/roslyn Wiki · GitHub

New Language Features in VB 14 · dotnet/roslyn Wiki · GitHub

新機能の詳細

Read-Onlyな自動実装プロパティと初期化

ついにRead-Onlyなプロパティの自動実装が実現しました。 いちいちバッキングフィールドを定義して長々とプロパティを手で書く手間から解放されたということですね。

ただ、個人的にはRead-Onlyな自動実装プロパティよりもセッターとゲッターでアクセス修飾子が異なるプロパティの自動実装の方が欲しかったです。

Read-Onlyなプロパティはフィールド初期化子っぽく初期化*1もしくはコンストラクタ内で初期化します。 当たり前ですが、コンストラクタ外では変更できないです。

ちなみに弊社は知らなかったのですが、C# 6 の新機能としてある自動実装プロパティのフィールド初期化子っぽい初期化はVBでは既にあったようです。

Public Class Person

    Public ReadOnly Property Name As String = "jyuch"
    Public ReadOnly Property age As Integer
    Public Property Weight As Double = 1.234

    Public Sub New(age As Integer)
        Me.age = age
    End Sub

    ' コンストラクタ外では変更不可
    'Public Sub Update()
    '    Me.Age = Me.Age + 1
    'End Sub
End Class

String interpolation

これは Groovy で言う所の GString みたいなもんです。 『いや、今まで一度も触れてこなかった言語を例に出されても知らねーよ』といった感じなので、サンプルコードをどうぞ。

Dim p = New Person(5)
Dim s = $"Name is {p.Name} Age is {p.Age} Weight is {p.Weight:0.0}"
Console.WriteLine(s)

Intellisense で補完ができるのでかなり便利です。

ちなみにコレはString.Formatの省略形の呼び出しです。

注意点として

  1. 現在のカルチャを使用しますよ
  2. 定数ではありませんよ

ってことだそうです。 いやまぁ定数じゃないってのは当たり前ですね。

あと、VBの方には書いてなかったんですがC#の方に式を埋め込む例がありましてVBの方でも試したら出来たんで一応紹介しておきます。

For it = 1 To 5
    Dim s = $"{it} year{If(it = 1, "", "s")}"
    Console.WriteLine(s)
Next

ちなみに、波かっこ自体を表現したい場合は二回続けて記述します。

Dim s = $"{it} {{year{If(it = 1, "", "s")}}}"

ちなみにちなみに、『FormattableStringは実際は一般的なメカニズムですよ〜』のくだりは弊社の英語力の限界サンプルがないのでとりあえずはパスという形でお願いします。

複数リテラル

個人的にやっと来たかという機能No.1です。

Dim x = "Hello" & vbCrLf & "World"
Dim Y = "Hello
World"
Dim z = $"Hello{vbCrLf}World"

ちなみに、改行リテラルは String interpolation を用いればそれっぽく出来ます。

Dim hoge = "hoge" & vbCrLf & "fuga" & vbCrLf & "hoge"

みたいなコードを書くたびに殺意が湧きまくりんぐだった弊社にとってはかなり嬉しいですね。

yyyy-MM-dd形式のDateTimeリテラル

Dim hoge = #2015-07-20#
Dim hoge2 = #2015-07-20 7:00 PM#

あ、うん。

モジュール、インターフェースの分割定義

クラスと同じようにPartialキーワードで分割で定義できるようになりました。

なりました。

NameOf演算子

NameOf演算子でクラス名やメソッド名、変数名などのキーワードを文字列としてコンパイル時に埋め込めるようになりました。

Dim x = 1
Console.WriteLine(NameOf(System.Console))
Console.WriteLine(NameOf(Module1.Main))
Console.WriteLine(NameOf(x))

一応呼び出し先から呼び出し元のメソッドもしくはプロパティ名を受け取るCallerMemberName属性なんてものがありましたが、適用できるのがメソッド呼び出しに限られていました。

そこで、NameOf演算子で変数名だろうがクラス名だろうがメソッド名だろうがコンパイル時に文字列リテラルとして埋め込めるようになりました。

注意点ですが、埋め込まれる文字列は末尾の最後の要素名になるということです。 上記の例ですと以下の実行結果になります。

Console
Main
x

Null-conditional 演算子

返り値にNothingが含まれる可能性のある場合など、いちいち返り値がNothingかどうかの判定を入れてから次の処理に進まなくてはならない場合があります。

そんな時の強い味方、Nothingかどうか判定しNothingだったらそのままNothing。 そうでなかったらメソッドやプロパティの呼び出しをしてくれるのが『Null-conditional』です。

Sub Main()
    Dim r = Hoge()
    Dim l As Integer? = r?.Length

    Console.WriteLine(l)
    Console.WriteLine(If(r?.Length, 0))
    Console.ReadLine()
End Sub

Function Hoge() As String
    Dim r = New Random()
    If r.Next(10) > 5 Then
        Return "hoge"
    Else
        Return Nothing
    End If
End Function

もっと細かい仕様とか説明があるのですが、うまく説明できそうにないので詳細はリンク先を参照してください。

その他

あとの細かいお話とかは、

  • 暗黙的な行の継続の後ろにコメントが書けるようになった
  • TypeOf ... IsNot ...構文の登場でNot TypeOf ... Is ...とか書かなくても済むようになった
  • 特定の警告を#Disable Warningプラグマで抑制できるようになった
  • インターフェースのRead-OnlyなプロパティをRead-Writeなプロパティとして実装できるようになった
  • 属性のパラメータ内でCObjが使えるようになった
  • XMLコメントドキュメントがなんか色々改善された

とかがあるっぽいです。

まとめ

駆け足での確認となりましたが、まぁ、だいたいこんな感じっぽいです。

説明の面倒なものや、弊社がそこまで興味のなかったものはかなり端折っています。 だったら最初っからこんな記事書くなよといった感じですが、その辺はまぁ露骨なアクセス数稼ぎ軽い紹介記事ってことで許してヒヤシンス。

あと、VBの新機能紹介の記事には必ずと言っていいほどこんな感じの文が書いてあるので、きっと書かなきゃいけない暗黙的なルールとかがあるのかな〜ってことで一応書いておきます。

これまでC#の後追いと言われてきたVB.NETであるが、今回のリリースでC#と遜色のないレベルの仕上がりを見せてきた。 今回のアップデートで業務向けアプリケーション開発でのVB.NETの地位は盤石なものとなった。 今まではVB.NET使いということで肩身の狭い諸君らであったが、これからは胸を張ってC#使いと対等に向き合うことができるだろう。

おわり

*1:正式な名前が分かりません。すいません。