tags:

views:

64

answers:

3

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

+4  A: 

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.

Ronald Wildenberg
It will work :-)
pst
+1  A: 

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!

pst
+1  A: 

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).

UserControl