C# 使用LINQ和委托执行递归函数

C# 使用LINQ和委托执行递归函数,c#,linq,C#,Linq,我的印象是Func和Action之间的唯一区别是前者必须有一个返回值,所以我认为可以从Func或Action调用递归linq。我是C语言的新手,我只是在尝试和好奇 因此,我尝试以下方法递归打印类型中的嵌套类型 Type t = typeof(Lev1); Action<Type> p1 = null, p2 = null; p1 = tn => { Console.WriteLine(tn.Name); tn.GetNeste

我的印象是Func和Action之间的唯一区别是前者必须有一个返回值,所以我认为可以从Func或Action调用递归linq。我是C语言的新手,我只是在尝试和好奇

因此,我尝试以下方法递归打印类型中的嵌套类型

 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);
因此,我得到的结果是,p1使用函数ie Select的递归只打印顶层,而p2使用动作ie Foreach打印所有层


我认为Func只是一个函数def,所以递归是有效的。当然,我的理解是错误的。有人能解释一下,为什么您在第一个实现中只看到顶层是因为。它只在需要时才开始返回值,例如,当您迭代它时,或者当您调用或许多其他函数时。如果在Select之后添加一个调用,它将起作用。

您在第一个实现中只看到顶级调用的原因是因为。它只在需要时才开始返回值,例如,当您迭代它时,或者当您调用或许多其他函数时。如果在Select之后添加调用,它将起作用。

您必须强制IEnumerable-它是懒惰的!不必总是这样,但要小心LINQ方法

在这种情况下,您将放弃结果和操作!。哦,好吧

您必须强制IEnumerable-它是懒惰的!不必总是这样,但要小心LINQ方法


在这种情况下,您将放弃结果和操作!。哦,好吧

您需要将.ToList添加到第一个Select调用中,因为Linq函数是惰性的。在第二个调用中,递归之所以有效,是因为List.ForEach的名称与ForEach语句的功能完全相同。

您需要将.ToList添加到第一个Select调用中,因为Linq函数是惰性的。在第二个调用中,递归之所以有效,是因为List.ForEach的名称与ForEach语句完全相同。

请不要在标题中重复标记C LINQ。如果我能教人们一件关于查询的事情,那就是:查询表达式的结果,比如调用Select,就是查询。查询和查询结果是两件完全不同的事情。查询表达式的结果是一个查询。如果需要该查询的结果,则必须请求执行该查询。现在,请注意,编写具有这种副作用的查询是最糟糕的做法。永远不要那样做。执行查询除了分配结果外,不应有任何副作用。谢谢eric-我知道编写带有副作用的选择不是一个好的做法。-我只是在试验,无法理解结果请不要重复标题中的标记C LINQ。如果我能教人们一件关于查询的事情,那就是:查询表达式的结果,比如调用Select,就是查询。查询和查询结果是两件完全不同的事情。查询表达式的结果是一个查询。如果需要该查询的结果,则必须请求执行该查询。现在,请注意,编写具有这种副作用的查询是最糟糕的做法。永远不要那样做。查询的执行除了分配结果之外应该没有任何副作用。谢谢eric-我知道写带有副作用的选择不是一个好的做法。-我只是在做实验,无法理解结果