はじめに
これは、Visual Basic Advent Calendar 2022の14日目の記事となります。
前記事にて、NuGetでRecGenパッケージをインストールして、VB.NETにレコード型を追加しました。
レコード型の応用例として、C#でDictionryのキーにレコード型を使うという記事を見つけました。
これをVB.NETでも試してみると、同じキーなのに例外エラーにならずに追加されてしまいました。
確認
ソースコード
Public Record PersonRecord (
FirstName As String = "",
LastName As String = ""
)
Module Program
Sub Main(args As String())
Dim obj1 As PersonRecord = New PersonRecord("Joe", "Blow")
Dim obj2 As PersonRecord = New PersonRecord("Joe", "Blow")
Try
Dim dict As New Dictionary(Of PersonRecord, String) From
{
{obj1, "sample1"},
{obj2, "sample2"}
}
Console.WriteLine(dict.Count) ' result 2
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Console.ReadKey()
End Sub
End Module
結果
Console.WriteLine(dict.Count)の2
が出力されます。
修正版
issueを書いた
RecGenの作者にissueを書きました。GetHashCodeが足りないですよってね。
最初に作者に上手く意図が伝わらず修正される前に危うく閉じられそうになったが、Microsoftに8年勤めVBの開発に関わった方が現れて、それはバグだ(This is definitely a bug in RecGen.)と指摘してくれて修正されました。
Equals を生成する場合、GetHashCode を生成する必要があります。microsoft documented.
バージョン更新
RecGenのバージョンが2.1から2.2にアップデートされました。
最終結果
Console.WriteLine(ex.Message)となり、「An item with the same key has already been added. Key: PersonRecord { FirstName = Joe, LastName = Blow }」が出力されました。
最後に
これで、ちゃんとしたレコード型が使えるようになりました。
下記は助けてくれた方のブログで、ModVBを開発している。
ModVBはVB.NETに新しい機能を追加するためのコンパイラのようです。mod の意味には、修正版 (modified)、modern (modern)、modulo operation (modulo) が含まれます。別途記事にしようと思います。