こんにちは。デカアキです。
ツリー構造の全ノードに対して何らかの処理を行うような場合、基本的には再起呼び出しを使用します。
例:フォーム内の全てのコントロールを列挙
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
private void Hoge() {
var allControl = new List<Control>();
HogeSub(this, allControl);
}
private void HogeSub(Control control, List<Control> allControl) {
foreach (Control obj in control.Controls) {
allControl.Add(obj);
HogeSub(obj, allControl);
}
}
|
上記のような感じのコードになりますが、これをActionデリゲートと匿名関数を使用して1つの関数で完結させます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
private void Hoge() {
var allControl = new List<Control>(); // ※a
Action<Control> action = null;// ※b
action = (control) => {
foreach (Control obj in control.Controls) {
allControl.Add(obj);// ※a
action(obj);// ※c
}
};
action(this);
}
|
この書き方でミソとなるのが
- ※b部分でActionデリゲート用の変数にいきなり匿名関数を設定するのではなく一旦、変数宣言だけを行う。
- その後、匿名関数をActionデリゲート用の変数に設定する。
- 上記のようにすることによって※c部分で自分自身(Actionデリゲート)を呼び出すことができます。
後者のメリットとしては
- 1つの関数で完結すること
- 本体側関数で定義してある変数が使用できる(※aの部分)
(※当然、呼び出されるタイミングを意識する必要はありますが)
といった感じです。
以上、小ネタでした。