VB.NETでもジェネリックなメソッドを実装したい

はじめに

特に需要なんてものはないんですが、VBで型パラメータで指定したインスタンスを生成したりするメソッドを定義したくなったのでちょっと調べてみました。

Module Module1

    Sub Main()

        Dim a As Generic1(Of HogeA) = New Generic1(Of HogeA)()
        Dim b As Generic1(Of HogeB) = New Generic1(Of HogeB)()

        Dim c As HogeA = a.Generate()
        Dim d As HogeB = b.Generate()
        c.HelloA()
        d.HelloB()

        Console.WriteLine()

        c = Generic2.Generate(Of HogeA)()
        d = Generic2.Generate(Of HogeB)()
        c.HelloA()
        d.HelloB()

        Console.ReadLine()
    End Sub

End Module

Class Generic1(Of T As {New, IHoge})
    Public Function Generate() As T
        Console.WriteLine("Generate():{0}", GetType(T))
        Dim i = New T()
        i.Hello()
        Return i
    End Function
End Class

Class Generic2
    Public Shared Function Generate(Of T As {New, IHoge})() As T
        Console.WriteLine("Generate():{0}", GetType(T))
        Dim i = New T()
        i.Hello()
        Return i
    End Function
End Class

Interface IHoge
    Sub Hello()
End Interface

Class HogeA
    Implements IHoge

    Public Sub HelloA() Implements IHoge.Hello
        Console.WriteLine("HogeA")
    End Sub
End Class

Class HogeB
    Implements IHoge

    Public Sub HelloB() Implements IHoge.Hello
        Console.WriteLine("HogeB")
    End Sub
End Class

メソッドHelloを宣言したインターフェースIHogeを定義し、型パラメータの制約として引数を取らないコンストラクタを持ちなおかつIHogeを実装したクラスのみを受け付けるクラスとメソッドを宣言しています。

それぞれのジェネリッククラス及びジェネリックメソッドは型パラメータのインスタンスを生成しインターフェースが宣言しているメソッドを実行してからインスタンスを呼び出し元へ返却しています。 なおNew制約を付けないとジェネリッククラス内でインスタンスの生成が出来ません。 当たり前ですね。型パラメータに渡されるクラスなんてジェネリッククラスの宣言時には分かりませんし、制約が無ければ引数を取らないコンストラクタを含まないクラスだって渡せます。そうなると実行時にコンストラクタの呼び出しに失敗します。

ちなみにジェネリックで指定した型であることを明示するために変数の型を明記してますが、

Dim c = a.Generate()

Dim c = Generic2.Generate(Of HogeA)()

でもちゃんと型推論してくれるので大丈夫です。

余談ですが、インターフェースを実装したクラスのメソッドを呼び出すとき、参照の型がインターフェースの場合はインターフェースで宣言したメソッド名を使用しますが、参照の型がクラスの場合はクラスで宣言したメソッド名で呼び出します。

さらに余談ですが、C#ではnew()制約は型パラメータ制約の最後にしないといけないという制約がありますが、VBではそういうのはないっぽいです。

型パラメーターの制約 (C# プログラミング ガイド) | Microsoft Docs

型リスト (Visual Basic) | Microsoft Docs

おしまい