Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
90 views
in Technique[技术] by (71.8m points)

c# - Recursion, can't make nested self object null, why is it so?

I am trying to update a list of self object in recursive code but it not doing, but when update the object by changing the values is working fine!

here is attached image for the output

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Node main = new Node();
            main.Sequence = "1";
            main.Id = 1;

            main.ChildNodes.Add(new Node()
            {
                Sequence = "1.1",
                Id = 2
            });
            main.ChildNodes.Add(new Node()
            {
                Sequence = "1.2",
                Id = 3
            });
            main.ChildNodes.Add(new Node()
            {
                Sequence = "1.3",
                Id = 4
            });
            Console.WriteLine("Before :");
            PrintNode(main);
            Console.WriteLine();
            MakeNull(main);

            Console.WriteLine("After :");
            PrintNode(main);

            void MakeNull(Node node)
            {
                foreach (var Child in node.ChildNodes)
                {
                    MakeNull(Child);
                }
                node.ChildNodes.RemoveAll(p => p == null);
                if (node.ChildNodes.Count == 0)
                {
                    node.Id = 5;//this is working 
                    node = null;//this is not, why ?
                }
            }

            Console.ReadLine();

        }
        static void PrintNode(Node node)
        {
            Console.WriteLine("Id:" + node.Id + " Sequence:" + node.Sequence);
            for (int i = 0; i < node.ChildNodes.Count; i++)
            {
                PrintNode(node.ChildNodes[i]);
            }
        }


    }
    public class Node
    {
        public int Id { get; set; }
        public string Sequence { get; set; }
        public List<Node> ChildNodes { get; set; }
        public Node()
        {
            ChildNodes = new List<Node>();
        }

    }
}

why it is not make whole object null?

question from:https://stackoverflow.com/questions/65939690/recursion-cant-make-nested-self-object-null-why-is-it-so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

To understand what happens, it is crucial to know that a class is a reference type. I.e., variables of this type contain either null or a reference to an object. They do not contain the object itself or the values stored in this object.

This is different from a value type like int. A variable of this type effectively contains the number it represents.


In void MakeNull(Node node), the parameter node holds a copy of the reference passed to it (because it is passed by value, i.e., without the ref or in or out keyword). You are only settings this copy to null. If you want to set the variable of the caller to null, you must pass it by reference:

void MakeNull(ref Node node)
{
    ...
    node = null;
    ...
}

Call it with

MakeNull(ref main);

or

MakeNull(ref Child);

Now, node is not a copy of the caller's variable but an alias of it. E.g., when you call

MakeNull(ref main);

... node is just another name for main. Setting node = null; now effectively sets main = null;.

Why does it work for node.Id = 5; then? Because node holds a reference to a Node object, and thus, the Id of this object is changed. Note that in your implementation you have a copy of a reference to a Node object in node, not a copy of the object itself.

See also my answer to this SO question: Setting a type reference type to null doesn't affect copied type?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...