LoginSignup
6
3

More than 1 year has passed since last update.

Visual Basicで「.NET 5.0 で使える C# 9.0の新機能」について調べてみた

Last updated at Posted at 2020-11-09

TL;DR

環境

  • 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

IsNotの間に空白を入れるとエラーとなります。
関連する議論: https://github.com/dotnet/vblang/issues/581

' エラーになります
If o Is Not Nothing Then
    ' Nothing じゃない
End If

参照記事のコメントに記載されていたObject.ReferenceEqualsについて

Object.ReferenceEqualsに、IDE0041を示してきました。

image.png

こちらを、.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

OpCodes.Ceq フィールド (System.Reflection.Emit) | Microsoft Docs

大なり小なりの比較も簡単に

Ifでは使えず、同様のことを行うにはSelect句を使用します。
💡 Ifの中でAnd Orで表現できたほうがわかりやすい気がします。

参考:
https://docs.microsoft.com/ja-jp/dotnet/visual-basic/language-reference/statements/select-case-statement

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

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3