ラムダ式、Adapterへの応用(C#)

アプリケーション開発では通常NetFrameworkなどの既製のライブラリを使用します。既製のライブラリは汎用的に作ってありますのでこれを開発しようとするシステムに合わせてより使いやすい中間的なライブラリを開発することがしばしば必要になります。例えばデータベース応用システムをNetFramworkで開発する場合、BindingSourceDataTableにバインドすることが圧倒的に多いわけのですが、BindingSourceは汎用的に作ってあるため使いにくいところがあります。そこでDataTableしかバインドできないけれどもそれ専用に使いやすいメソッドを備えたクラスを新たに開発することもこれに該当します。提供される機能と必要とする機能が一致しないためその差を埋める必要があるわけです。

粒度の小さい例ではイベントハンドラの引数があります。イベントを発生させたオブジェクトがsenderに付加的な情報がeに渡されますが、これらを使用することは私の場合あまりなくてむしろ別の引数が欲しいことが多いのです。電卓のようなアプリケーションを考えると数字ボタンはたくさんありますが0から9まで行っている処理はそれぞれの数値入力を受け取ることです。sendereが不要で入力した数値が必要となります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//IDEでイベントハンドラを作成
private void button1_Click(object sender, EventArgs e) {
Console.WriteLine('1');
}

//Adapterクラス
private class Adapter {
char _letter;

public Adapter(char letter) {
_letter = letter;
}

public void Handler(object sender, EventArgs e) {
Console.WriteLine(_letter);
}
}

//ラムダ式を使ったアダプタ
private EventHandler AdapterByLambda(char letter) {
return (sender, e) => Console.WriteLine(letter);
}

private void Form1_Load(object sender, EventArgs e) {
button2.Click += new Adapter('2').Handler; //Adapterクラスを使用
button3.Click += AdapterByLambda('3'); //ラムダ式を使ったアダプタを使用
button4.Click += (sender1, e1) => Console.WriteLine('4'); //その場でラムダ式を記述
}

右記サンプルコードを試すにはWindows Formを作成して、ボタンを4つ貼り付けてください。実行結果は出力ウィンドウで確認します。

IDEでは簡単にイベントハンドラを作れますので10個のイベントハンドラを作ることも一つの方法として考えられます。Button1がこの方法でイベントハンドラを設定しています。

別の方法はAdapterクラスを作ることです。数値をクラスのメンバー_letterに代入しておき、EventHandler形式のメソッドとしてイベントハンドラを取り出します。Button2がこの方法でイベントハンドラを設定しています。

ラムダ式を使うとアダプタを簡単に記述できます。Button3がこの方法でイベントハンドラを設定しています。リスト中のAdapterByLambdaを見てください。ラムダ式はメソッド(ポインタ)を返す式で=>の左辺が引数、右辺がメソッド本体を表します。各引数の型は型推論により指定不要です。メソッド本体が複文になるときは{}で囲みます。AdapterByLambdaを呼び出したときにラムダ式が返すメソッドが実行されるわけではありません。AdapterByLambdaの引数letterはラムダ式実行時にも保持されています。

アダプタがこれだけ単純になるのならと、Button4はアダプタを使わないで直接ラムダ式を記述しています。アダプタを他で再利用しないならこのような簡便な方法も使えます。