递归调用 Func 并不总是可行

发布于 2024-10-11 01:40:53 字数 2339 浏览 1 评论 0原文

我有以下代码,它执行非常简单的操作:递归访问 Node 对象树并计算名为 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; }
    }    
}

我的问题和问题是:为什么我不能在方法中使用该函数?我收到错误:使用未分配的局部变量“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; }
    }    
}

I have the following code that does something very simple: visits recursively a tree of Node objects and calculates the sum of a property named 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; }
    }    
}

A better solution would be

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

My problem and question is: why I can't have the function inside the method? I am getting error: Use of unassigned local variable '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; }
    }    
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

似最初 2024-10-18 01:40:54

可以在方法中拥有它,您只需要稍微捏造一些东西就可以绕过这样一个事实:赋值表达式的 RHS 包含使用未明确分配的局部变量

Func<Node, int> fSum = null;
fSum = node => node.Info + (node.Left == null ? 0 : fSum(node.Left)) 
                         + (node.Right == null ? 0 : fSum(node.Right));

:解决了明确的分配问题。偶尔会有点烦人,你可以想象修复它会很好......但可能有一些有趣的情况,它确实是一个问题,但相对难以用语言术语描述。

换句话说:我怀疑修复明确的赋值规则,以便仅在安全的情况下才允许在 lambda 表达式中读取局部变量(其中 lambda 表达式是赋值变量 的一部分,并且 委托在分配发生后才会被执行)会比相对少量的好处增加更多的复杂性。

You can have it within the method, you just need to fudge things a bit to get around the fact that the RHS of your assignment expression includes the use of a local variable which isn't definitely assigned:

Func<Node, int> fSum = null;
fSum = node => node.Info + (node.Left == null ? 0 : fSum(node.Left)) 
                         + (node.Right == null ? 0 : fSum(node.Right));

That gets around the definite assignment issue. It's slightly annoying occasionally, and you can imagine that it would be nice to fix... but there could be some interesting situations where it's genuinely a problem, but relatively hard to describe in language terms.

To put it another way: I suspect that fixing the definite assignment rules to allow a local variable to be read within a lambda expression only where it would be safe to do so (where the lambda expression is part of assigning the variable and the delegate doesn't get executed until after the assignment has taken place) would add more complexity than the relatively small amount of benefit.

赏烟花じ飞满天 2024-10-18 01:40:54

正如它所说,您不能使用 fSum,因为直到该行末尾它才完全分配。如果您声明它,将其设置为 null,然后将其设置为该值,它将起作用。

As it says, you can't use fSum because it isn't fully assigned until the end of that line. If you declare it, set it to null, and then set it to that value, it will work.

迎风吟唱 2024-10-18 01:40:54
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();
}
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();
}
节枝 2024-10-18 01:40:54

将其写为:

Func<Node, int> fSum = null;
fSum= (node) => node.Info + (node.Left == null ? 0 : fSum(node.Left)) + (node.Right == null ? 0 : fSum(node.Right));

Write it as:

Func<Node, int> fSum = null;
fSum= (node) => node.Info + (node.Left == null ? 0 : fSum(node.Left)) + (node.Right == null ? 0 : fSum(node.Right));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文