ジェネリック(クラス)

型引数を持ったクラスを使い、Formの生成にジェネリックを応用した例を紹介します。

IDEを使ってWindowsFormを設計すると、Formの派生クラスが作られていきます。Formを生成する汎用的なプロシージャを作ろうとすると、それぞれのフォームが異なる型を持つことがネックになります。Win32版のDelphiならクラス参照型によってあっさり実現できるのですがNet
Frameworkではそうも行きません。一つの方法としてはReflectionを使ってそれぞれの型に応じたコンストラクタを呼び出す方法があります。これはコンストラクタを取得するのに比較的複雑なコードを書かなければなりませんし、アプリケーションアーキテクチャとしてReflectionを使うのならまだしも、Formを生成するのにReflectionを持ち出してくることはエレガントとは言えません。そこでジェネリックを使うのです。

以下のクラスは汎用的にフォームを生成・オープンするメソッドを持つクラスです。

1
2
3
4
5
6
7
8
9
Public Class OpenFormCommand(Of TForm As {Form, New})
Dim _form As TForm

Public Sub Execute(ByVal sender As Object, ByVal e As EventArgs)
If _form Is Nothing OrElse _form.IsDisposed Then _form = New TForm
_form.Show()
_form.BringToFront()
End Sub
End Class

型引数TFormはオープンするフォームの型です。型制約としてFormとNewを指定しています。一度生成されたら2度目以降同じオブジェクトを再利用するようにしています。Executeが生成・オープンするメソッドです。イベントハンドラとして扱えるようにsenderとeを付けていますが、これらの引数は使用していません。

このクラスを利用するフォームのコードです。フォームには2つのボタンが配置してあり、ボタンを押せばそれぞれ異なるフォームを表示することを想定しています。メインメニューではありがちなインタフェースだと思います。

1
2
3
4
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
AddHandler Button1.Click, AddressOf (New OpenFormCommand(Of Form2)).Execute
AddHandler Button2.Click, AddressOf (New OpenFormCommand(Of Form3)).Execute
End Sub

フォームのロード時に、OpenFormCommandクラスのExecuteメソッドを2つのボタンのクリック時イベントハンドラとして登録しています。このようにするとイベントハンドラをボタン毎に記述する必要がなくなります。