C#实现递归调用的Lambda表达式

C#实现递归调用的Lambda表达式

前段时间,我写一个树的访问算法的时候,用了Visitor模式把访问的算法分离了出来,当时打算用lambda表达式写visit算法的,却发现带递归调用的lambda表达式没想象的那么好写,憋了半天愣是没写出来,由于当时赶进度,就写成了普通的函数了。

今天晚上研究了一下递归调用的Lambda表达式的写法,发现也还是比较简单的,就是脑袋要转个弯(可能当时这个弯没有转过来),首先给一个简单的示例:

int i = 1; RecursiveRun(self => { Console.WriteLine("hello world " + i++); self(); }); static void RecursiveRun(Action<Action> action) { action(() => RecursiveRun(action)); }

可能有人说函数RecursiveRun是无参数的,基本上没什么用,下面这个就是带一个参数的版本了(如果需要更多的参数的版本,直接把RecursiveRun函数稍稍修改即可):

static void RecursiveRun<T>(T obj, Action<T, Action<T>> action) { action(obj, o => RecursiveRun(o, action)); }

通过这个函数,就可以把二叉树的遍历算法用lambda表达式给表示出来了:

class BinTree { public int Value { get; set; } public BinTree Left { get; set; } public BinTree Right { get; set; } public BinTree(int value) { this.Value = value; } public void Accept(Action<BinTree> visitor) { visitor(this); } public void Accept(Action<BinTree, Action<BinTree>> visitor) { visitor(this, node => node.Accept(visitor)); } public override string ToString() { return Value.ToString(); } } var nodes = Enumerable.Range(0, 5).Select(i => new BinTree(i)).ToArray(); nodes[0].Left = nodes[1]; nodes[0].Right = nodes[2]; nodes[1].Left = nodes[3]; nodes[1].Right = nodes[4]; nodes[0].Accept((node, visitor) => { Console.WriteLine(node.Value); if (node.Left != null) visitor(node.Left); if (node.Right != null) visitor(node.Right); });

推荐阅读