C# 递归调用Func并不总是可能的
我有以下代码可以做一些非常简单的事情:递归地访问节点对象树并计算名为Info的属性的总和C# 递归调用Func并不总是可能的,c#,.net,lambda,functional-programming,C#,.net,Lambda,Functional Programming,我有以下代码可以做一些非常简单的事情:递归地访问节点对象树并计算名为Info的属性的总和 using System; namespace ConsoleApplication11 { static class Program { static void Main(string[] args) { //tree of nodes var node = new Node {Info = 1, Left
using System;
namespace ConsoleApplication11
{
static class Program
{
static void Main(string[] args)
{
//tree of nodes
var node = new Node {Info = 1, Left = new Node {Info = 1}};
//print out sum
Console.WriteLine(node.Sum());
Console.ReadLine();
}
//find sum of Info of each node
static int Sum(this Node node)
{
return node.Info + (node.Left == null ? 0 : Sum(node.Left)) + (node.Right == null ? 0 : Sum(node.Right));
}
}
public class Node
{
public int Info { get; set; }
public Node Left { get; set; }
public Node Right { get; set; }
}
}
更好的解决办法是
using System;
namespace ConsoleApplication11
{
static class Program
{
static Func<Node, int> fSum = (node) => node.Info + (node.Left == null ? 0 : fSum(node.Left)) + (node.Right == null ? 0 : fSum(node.Right));
static void Main(string[] args)
{
//tree of nodes
var node = new Node {Info = 1, Left = new Node {Info = 1}};
//print out sum
Console.WriteLine(fSum(node));
Console.ReadLine();
}
}
public class Node
{
public int Info { get; set; }
public Node Left { get; set; }
public Node Right { get; set; }
}
}
使用系统;
命名空间控制台应用程序11
{
静态类程序
{
静态函数fSum=(node)=>node.Info+(node.Left==null?0:fSum(node.Left))+(node.Right==null?0:fSum(node.Right));
静态void Main(字符串[]参数)
{
//节点树
var node=newnode{Info=1,Left=newnode{Info=1};
//打印金额
Console.WriteLine(fSum(node));
Console.ReadLine();
}
}
公共类节点
{
公共整数信息{get;set;}
左公共节点{get;set;}
公共节点权限{get;set;}
}
}
我的问题是:为什么我不能在方法中使用函数?我遇到错误:使用未分配的局部变量“fSum”
using System;
namespace ConsoleApplication11
{
static class Program
{
static void Main(string[] args)
{
//I am getting error: Use of unassigned local variable 'fSum'
Func<Node, int> fSum = (node) => node.Info + (node.Left == null ? 0 : fSum(node.Left)) + (node.Right == null ? 0 : fSum(node.Right));
//tree of nodes
var n = new Node {Info = 1, Left = new Node {Info = 1}};
//print out sum
Console.WriteLine(fSum(n));
Console.ReadLine();
}
}
public class Node
{
public int Info { get; set; }
public Node Left { get; set; }
public Node Right { get; set; }
}
}
使用系统;
命名空间控制台应用程序11
{
静态类程序
{
静态void Main(字符串[]参数)
{
//我遇到错误:使用未分配的局部变量“fSum”
Func fSum=(node)=>node.Info+(node.Left==null?0:fSum(node.Left))+(node.Right==null?0:fSum(node.Right));
//节点树
var n=新节点{Info=1,Left=新节点{Info=1};
//打印金额
控制台写入线(fSum(n));
Console.ReadLine();
}
}
公共类节点
{
公共整数信息{get;set;}
左公共节点{get;set;}
公共节点权限{get;set;}
}
}
正如它所说的,您不能使用fSum,因为直到该行结束时它才被完全分配。如果您声明它,将其设置为null,然后将其设置为该值,它将起作用。您可以在方法中使用它,您只需要稍微捏造一些东西,以避免赋值表达式的RHS包括使用未明确赋值的局部变量:
Func<Node, int> fSum = null;
fSum = node => node.Info + (node.Left == null ? 0 : fSum(node.Left))
+ (node.Right == null ? 0 : fSum(node.Right));
Func fSum=null;
fSum=node=>node.Info+(node.Left==null?0:fSum(node.Left))
+(node.Right==null?0:fSum(node.Right));
这就绕过了明确的分配问题。偶尔会有点烦人,你可以想象修复它会很好。。。但可能会有一些有趣的情况,这确实是一个问题,但用语言来描述却相对困难
换一种说法:我怀疑修正了明确的赋值规则,只允许在安全的情况下(lambda表达式是赋值变量的一部分,并且直到赋值发生后才执行委托),才允许在lambda表达式中读取局部变量将比相对较少的好处增加更多的复杂性。静态void Main(string[]args){
static void Main(string[] args) {
//Declare the local variable first.
Func<Node, int> fSum = null;
//We are now able to reference the local variable from within the lambda.
fSum = (node) =>
node.Info + (node.Left == null ? 0 :
fSum(node.Left)) + (node.Right == null ? 0 :
fSum(node.Right));
//tree of nodes
var n = new Node {Info = 1, Left = new Node {Info = 1}};
//print out sum
Console.WriteLine(fSum(n));
Console.ReadLine();
}
//首先声明局部变量。
Func fSum=null;
//我们现在可以从lambda中引用局部变量。
fSum=(节点)=>
node.Info+(node.Left==null?0:
fSum(node.Left))+(node.Right==null?0:
fSum(node.Right));
//节点树
var n=新节点{Info=1,Left=新节点{Info=1};
//打印金额
控制台写入线(fSum(n));
Console.ReadLine();
}
将其写成:
Func<Node, int> fSum = null;
fSum= (node) => node.Info + (node.Left == null ? 0 : fSum(node.Left)) + (node.Right == null ? 0 : fSum(node.Right));
Func fSum=null;
fSum=(node)=>node.Info+(node.Left==null?0:fSum(node.Left))+(node.Right==null?0:fSum(node.Right));
…启用相互递归需要更高的复杂性,而空初始化解决方案也适用于此。这是重复的是重复的。对不起,我不知道。