勉強会お疲れさんでしたー のつづき、つかアフタケア。
LTは「TreeViewの全ノードを列挙する」てのを
再帰+yield で実装する五分間コーディング。
TreeViewにあるノード(TreeNode)を列挙してListBoxに流し込んだのんね。
フツーに書けば:
private delegate void Action(TreeNode node);
// TreeNodeのFullPathをListBoxに流し込む
private void AddItem(TreeNode node) {
listBox1.Items.Add(node.FullPath.Replace('\\', ' '));
}
// 列挙開始!
private void button1_Click(object sender, EventArgs e) {
walk_tree(treeView1, AddItem); // TreeViewに対し「列挙しろ!」
}
private static void walk_tree(TreeView tree, Action act) {
// TreeViewの持つNodeに対し「列挙しろ!」
foreach (TreeNode node in tree.Nodes)
walk_node(node, act);
}
private static void walk_node(TreeNode node, Action act) {
act(node); // なんかして、
// その子Nodeに対して「列挙しろ!」
foreach (TreeNode child in node.Nodes)
walk_node(child, act);
}
とまぁ、こんな感じになるっしょ。
再帰の末端でなんかしてます。
これを 再帰+yield 使って「呼び出されたその場でなんかする」よに
書き変えたわけっす。
// 列挙開始!
private void button1_Click(object sender, EventArgs e) {
// TreeView内の全Nodeに対し
foreach ( TreeNode node in enum_tree(treeView1))
AddItem(node); // なんかする
}
// tree内の全Nodeを列挙する
private static IEnumerable<TreeNode> enum_tree(TreeView tree) {
foreach (TreeNode child in tree.Nodes)
foreach (TreeNode result in enum_node(child))
yield return result;
}
// nodeおよびその子Nodeを列挙する
private static IEnumerable<TreeNode> enum_node(TreeNode node) {
yield return node;
foreach (TreeNode child in node.Nodes)
foreach (TreeNode result in enum_node(child))
yield return result;
}
これでなんかオイシイことがあるかっちゅーと、えーと...