开发者

Doing Recursive Function using LINQ and Delegates

I was under the impression that the only difference between Func and Action is that the former has to have a return value.So I thought you can call a recursive linq from either a Func or Action. I am new to C# and I am just experimenting and curious.

So I tried the following to recursively print the nested types within a Type.

 Type t = typeof(Lev1);
 Action<Type> p1 = null, p2 = null;
 p1 = tn =>
     {
         Console.WriteLine(tn.Name);
         tn.GetNestedTypes().Select(x => { p1(x); return x; });
     };
 p2 = tn =>
     {
         Console.WriteLine(tn.Name);
         tn.GetNestedTypes().ToList().ForEach(x => { p2(x);});
     };
 p1(t);
 Console.WriteLine("=".PadRight开发者_如何学运维(50, '='));
 p2(t);

So the result I got was that p1 (which uses recursion from a Func-ie Select) only prints the top level whereas p2 which uses Action-ie Foreach prints all levels.

I thought Func is just a function def so recursion is valid. Sure my understanding is wrong can somebody explain


The reason you see only the top-level in the first implementation is because the Select is lazily evaluated. It only starts returning values when it needs to, for example when you iterate it (or when you call Sum or a number of other functions). If you add a ToList() call after the Select, it will work.


You must force the IEnumerable -- it is lazy! (It needn't always be, but be wary with LINQ methods!)

In this case, you discard the results (and the actions!). Oh, well!


You need to add .ToList() to the first Select() call because Linq functions are lazy. In the second call the recursion works because of List<>.ForEach() (which as the name stands does exactly what foreach statement does).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜