Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 递归调用Func并不总是可能的_C#_.net_Lambda_Functional Programming - Fatal编程技术网

C# 递归调用Func并不总是可能的

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

我有以下代码可以做一些非常简单的事情:递归地访问节点对象树并计算名为Info的属性的总和

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

…启用相互递归需要更高的复杂性,而空初始化解决方案也适用于此。这是重复的是重复的。对不起,我不知道。