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

時間の掛かる計算処理が終わったときに終了メッセージを表示したり、例外処理やトランザクションの様に特定のコンテキストで、何らかの処理を行いたいことがあります。これらの事前処理や事後処理をラムダ式や匿名メソッドを使わないで実現することは面倒なものです。終了メッセージの例では計算処理本体が既にメソッドになっている場合に、計算処理の後に終了メッセージを表示するだけのメソッドを新たに書かなければなりません。例外処理の例では汎用的な例外処理で済む場合にもTry
Catchをその都度記述するか、汎用的な例外処理を行うメソッドを作ったにしても、Try Catchの内側をメソッドとして独立させなければなりません。

このような場合にラムダ式を使うとメソッドの数が減り、一続きの処理なのに記述箇所が散らばってしまうのを避けることできます。

Form1のコード
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
private void HeavyOperation() {
Console.WriteLine("時間の掛かる処理");
System.Threading.Thread.Sleep(1000);
}

private void Form1_Load(object sender, EventArgs e) {
button1.Click += Lib.ToEventHandler(() => MessageBox.Show("button1.Click"));
button2.Click += Lib.ToEventHandler(() => {
HeavyOperation();
MessageBox.Show("時間のかかる処理を実行しました.");
});
button3.Click += Lib.ToEventHandler(
Lib.GetExceptionTrapAction(() => {
var a = 0;
var b = 0;
var c = a / b;
})
);
<span class=code-comment>/*
button4.Click += Lib.ToEventHandler(Lib.ShowForm2AndExecute(() => {
HeavyOperation();
MessageBox.Show("時間のかかる処理を実行しました.");
}));
*/</span>
}

サンプルコードはAdapterの例と同様にフォームのロード時に各ボタンのイベントハンドラを設定しています。

Button1はクリックしたらメッセージを表示するだけの単純な処理です。Lib.ToEventHandlerは引数・戻り値のないメソッドをEventHandlerに変換するライブラリのメソッドです。

Button2は時間の掛かる計算処理が終わったときに終了メッセージを表示する例です。HeavyOperationは処理本体です。HeavyOperationとメッセージ表示を順次実行する短い処理をラムダ式で表現しています。
Button3はゼロでの割り算により例外が発生する処理です。Lib.GetExceptionTrapActionは処理を汎用的な例外処理コンテキストの下で実行するメソッドです。この場合はTry
Catchの内側の処理をラムダ式で指定しています。

印刷処理などでは印刷前にタイトルを入力したり、データ抽出などの指定を行うために別フォームを表示することがあると思います。指定用のフォームをいろんな帳票に使い回すケースもよくあります。そんなとき起動したフォームから指定用のフォームの「実行」ボタンが押されたときの処理を渡す必要があります。これを簡潔に書くためにラムダ式を使います。