VB15の新機能の確認したい

はじめに

3月7日にVisual Studio 2017がリリースされました。

と言うことで今回も露骨なアクセス稼ぎVB15の新機能を確認していきましょう。

どうでもいいですが、VS2017のアイコンって梵字っぽいですよね。筆で書かれたっぽくして色を周りに合わせたら紛れてても気付かなそう。

新機能

新機能はこちらにまとまっているっぽいです。

今回もプログラミングの効率を上げる嬉しい新機能が目白押しではありませんでした。ざんねん

  • 値タプル
  • ByRefによる使用量の戻り値
  • 二進数リテラルと桁区切り

上二つはなんかC#7.0との互換性の為に導入された感がありますし、二進数リテラルも『はぁ、そうですか』感が否めません。

まぁ、とりあえず確認していきましょう。

値タプル

タプルと言えば.NET Framework 4からSystem.Tupleが存在しました。 存在しましたが2つ程欠点が存在しました。

  • System.Tupleは参照型で何だかんだ言ってメモリの使用効率とGCのペナルティが発生する
  • タプルの要素へのアクセスにItem1Item2などといった人の温もりの感じられない名前で扱わないといけない

この2つの問題の解決策として導入されたのが値型のタプルであるSystem.ValueTupleと言語機能による名前付きタプルのサポートです。

値型であるため、何だかんだ言ったメモリの使用効率の改善とGCペナルティの削減が図られています。 がこちらは遅延バインディングと暗黙の型変換とアンリミテッドボックス化ワークスにまみれているVBプログラマには関係ありませんGCによる予測困難な遅延の発生を極限まで抑えたい(≒ゲーム実装)などで効いてくることですので、VBの主戦場である生産性アプリケーションではほとんど関係ありません。正直パフォーマンスは二の次で良いから読めるコードを書いてくれ頼む

で、前置きが長くなりましたがVB15の新機能の1つ目の名前付きタプルのお時間です。

あの無味乾燥で温かみの感じられないItem1などの名前ではなく、SyohizeiKingakuといった温かみのある名前で扱えるようになります。

Function HogeOld(a As IEnumerable(Of Integer)) As Tuple(Of Integer, Integer)
    Return Tuple.Create(a.Min(), a.Max())
End Function

Function Hoge(a As IEnumerable(Of Integer)) As (min As Integer, max As Integer)
    Return (a.Min(), a.Max())
End Function
Dim a = {1, 2, 3, 4, 5, 6, 7, 8, 9}
Dim b = HogeOld(a)
Dim c = Hoge(a)

Console.WriteLine($"min={b.Item1} max={b.Item2}")
Console.WriteLine($"min={c.min} max={c.max}")

もしかしたら弊社の環境が壊れているだけかもしれませんが、この機能はなぜかソリューションを作成しただけでは使えません。

f:id:jyuch:20170310213904p:plain

定義済みの型は定義されていません

とは面妖なエラーメッセージですが、どうにかして解決しましょう。

System.ValueTupleの方はNuGetパッケージをインストールすると解決します。

PM> Install-Package System.ValueTuple

属性の方はNuGetパッケージの方にもないっぽいのでCoreFXのコードからコピペで対応します。

github.com

C#なら単純なコピペで行けますが、VBの場合はVBコードに脳内トランスパイルするか別プロジェクトとしてC#でコピペして参照を追加する必要があり軽い敗北感すら感じます。

ということでパパッとVBコードとして書き換えます。

Namespace Global.System.Runtime.CompilerServices

    <CLSCompliant(False)>
    <AttributeUsage(AttributeTargets.Field Or AttributeTargets.Parameter Or AttributeTargets.Property Or AttributeTargets.ReturnValue Or AttributeTargets.Class Or AttributeTargets.Struct Or AttributeTargets.Event)>
    Public NotInheritable Class TupleElementNamesAttribute
        Inherits Attribute

        Private ReadOnly _transformNames As String()

        Public Sub New(transformNames As String())
            If transformNames Is Nothing Then
                Throw New ArgumentNullException(NameOf(transformNames))
            End If

            _transformNames = transformNames
        End Sub

        Public Function TransformNames() As IList(Of String)
            Return _transformNames
        End Function

    End Class

End Namespace

ByRefによる使用量の戻り値

誤訳なんじゃねーのってくらい意味が分かりませんが、機能の方も同じくらい意味が分かりません。

何よりも動くサンプルコードが現状見当たりません。

たぶんC#ref returnに対応する何かなんだと思います。

二進数リテラルと桁区切り

Dim answer = &B0010_1010
Console.WriteLine($"生命、宇宙、そして万物についての究極の疑問の答え = {answer}")
生命、宇宙、そして万物についての究極の疑問の答え = 42

おわりに

VB14でC#6.0との言語格差がかなり縮まったのでVBの今後に期待したのですが、VB15とC#7.0で差はまた開きつつありますね。

ちなみにC#7.0の新機能はこちらです。

blogs.msdn.microsoft.com

あくまでも個人的な感想ですが、VBC#は手続き型・オブジェクト指向プログラミング言語として(F#と比べて)かなり近い立ち位置にいると思います。 そんなパラダイムもベースとなるクラスライブラリ群もランタイムも共有する2つの言語を同じようにマイクロソフトがメンテナンスしていくかどうかには疑問を感じます。

VB.NETはVB6からC#への過渡期にVB6プログラマーC#にスムーズに移行させるために作られた。かどうかは分かりませんが現状を見るとC#VBのどちらに未来があるかといわれるとC#に軍配が上がるのは明らかです。 VBは初心者向けなんて言われることがありますが、少なくともVB.NETC#は同じオブジェクト指向というパラダイムの上に成り立っている言語ですから言語としての複雑さは同程度なはずです。むしろ書籍・コミュニティの充実しているC#のほうが学びやすいのではないでしょうか。 仮にVBプログラマC#を理解できないというのなら、それはC#が複雑だからではなくVBすら良く分かってない可能性があります。

とまぁ、お前はVBの何なんだよと言われそうな感じですが、弊社としてはVBは嫌いではないです。 ただ、恐らくはいずれC#(もしくは次の言語)に乗り換えないといけない時が来るのでいつまでも塩漬けにしておくのは得策ではありませんよって事です。

おわり