TL;DR
-
C# 小ネタ:.NET 5.0 で使える C# 9.0 で気に入ってる機能紹介について、Visual Basicでの状況について調査してみました。
.NET 5.0で互換性を考慮したサポートは発表されていますが、把握している限り言語的な更新は入っていません。
環境
- Visual Studio 2019 Version 16.7.6
レコード型
サポートされていません。
ただし、
https://qiita.com/yaju/items/b1c58162eb634fd58619
によると、直近では、Visual Basicでレコード型を実装する試みがされているそうです。
I hate C# records. Please don't ever bring them to VB!
トップレベルステートメント
サポートされていません。
null じゃないんですよを簡単に書ける
IsNot
を使います。
' 不等号を使う
If (o <> Nothing) Then
' Nothing じゃない
End If
' IsNotを使う
If o IsNot Nothing Then
' Nothing じゃない
End If
Is
と Not
の間に空白を入れるとエラーとなります。
関連する議論: https://github.com/dotnet/vblang/issues/581
' エラーになります
If o Is Not Nothing Then
' Nothing じゃない
End If
参照記事のコメントに記載されていたObject.ReferenceEqualsについて
Object.ReferenceEqualsに、IDE0041を示してきました。
こちらを、.NET Core 3.1を利用して逆アセンブルしてみました。.NET 5.0での検証は環境がないため未実施です。
生成されるMSILは異なります。C#での例を考えると同じことを表現している気もします。
ソースコードとMSIL(逆アセンブル)の結果
VB.NET
Sub Main()
Dim o = New Sample
If o Is Nothing Then
End If
If Object.ReferenceEquals(o, Nothing) Then
End If
End Sub
MSIL
.method public static void Main(string[] args) cil managed
{
.entrypoint
.custom instance void [System.Runtime]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )
// コード サイズ 31 (0x1f)
.maxstack 2
.locals init (class ConsoleApp2.Sample V_0,
bool V_1,
bool V_2)
IL_0000: nop
IL_0001: newobj instance void ConsoleApp2.Sample::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldnull
IL_0009: ceq
IL_000b: stloc.1
IL_000c: ldloc.1
IL_000d: brfalse.s IL_0010
IL_000f: nop
IL_0010: nop
IL_0011: ldloc.0
IL_0012: ldnull
IL_0013: call bool [System.Runtime]System.Object::ReferenceEquals(object,
object)
IL_0018: stloc.2
IL_0019: ldloc.2
IL_001a: brfalse.s IL_001d
IL_001c: nop
IL_001d: nop
IL_001e: ret
} // end of method Program::Main
大なり小なりの比較も簡単に
Ifでは使えず、同様のことを行うにはSelect句を使用します。
💡 Ifの中でAnd Orで表現できたほうがわかりやすい気がします。
If
では使えません。
Dim x = 15
'エラーになります
If (x Is >= 10 And <= 20) Then
Console.WriteLine("10 以上で20 以下")
End If
'エラーになります
If (x Is >= 10 And <= 20 Or >= 100) Then
Console.WriteLine("10 以上で20 以下もしくは 100 以上")
End If
Select Case
では以下の記載となります。
Dim x = 15
Select Case x
Case 10 To 20
Console.WriteLine("10 以上で20 以下")
End Select
'1行で記載した場合
Select Case x : Case 10 To 20
Console.WriteLine("10 以上で20 以下")
End Select
Select Case x : Case 10 To 20, >= 100
Console.WriteLine("10 以上で20 以下もしくは 100 以上")
End Select
Target-typed new 式
サポートされていません。
まとめ
やはり、言語仕様の更新が頻繁に行われているというのはうらやましいものがあります。
特に、Record型はうらやましいですね。
「null じゃないんですよを簡単に書ける」や「大なり小なりの比較も簡単に」などの記法は、逆に影響を与えている面もあるかもしれません。C# に移行するとswitchの記法は少し面倒に感じましたので。
参考までに、Visual Basicの言語仕様に関する議論はここで行われています。
https://github.com/dotnet/vblang/issues