简体   繁体   中英

Why can't I instantiate an object in a function

So basically I have a class NodeTree:

public class NodeTree
{
    public NodeTree(int value, NodeTree left, NodeTree right)
    {
        Value = value;
        Right = right;
        Left = left;
    }

    public int Value { get; set; }
    public NodeTree Right { get; set; }
    public NodeTree Left { get; set; }
}

And in my main I want to do something like

NodeTree root = null;
Algo.InsertValueIt(root, 8);

Where InsertValueIt() is a method from my static class Algo which does :

 public static void InsertValueIt(NodeTree root, int val)
    {
        var newNode = new NodeTree(val, null, null);
        if (root == null)
        {
            root = newNode;
        }
    }

Everything is working as expected in my method, but back to my main, my object root is still null. The reason I am confused is that I give to my method a reference, so it should modify the value of the adress to the new space I am allocating.

I think I can solve my problem by just returning a NodeTree, but is there a way of doing it with a void return type?

You need to define your argument to be passed by reference in order to modify the original value (note the ref keyword):

public static void InsertValueIt(ref NodeTree root, int val) {
    ...

Also when calling the method, you need to mark the parameter with ref :

Algo.InsertValueIt(ref root, 8);

... otherwise you only modify the local copy in that function.

What happens when you pass a reference type to a method?
The variable declared to be of a reference type holds the memory address where the instance of the type has been allocated (the root in the calling code). The value of this address is copied to a new variable created on the stack for the called method (the root in the InsertValueIt ). Using that address through the new variable you will be able to change every public property of the instance or call any methods (provided that the address passed is not null).

What happens now if you call new on this local variable?
A new block of memory is allocated on the heap for the type, the constructor is called to initialize everything, and the memory address of this block is stored in the LOCAL variable inside the InsertValueIt .

Your original one, (the root in the calling code), is unaffected by this change. (still holds null). Using the ref keyword makes the this 'problem' disappear, but I suggest to use a method that creates the Node and return it to the calling method instead.

If you want to understand in more depth this subject I recommend these two articles:

C#Concepts: Value Types vs Reference Types from Joseph Albahari
Parameter Passing in C# from Jon Skeet

您在InsertValueIt中分配的根值未在任何执行路径中使用,因此应在参数声明中添加ref关键字。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM