I am having trouble understanding how object manipulation is working in C# methods. I know that when you pass an object to a method, a reference to that object is passed. With that in mind, I figured that option 1 would work like this:
- The root variable comes into the method as a reference to root
- When you set it to root.left it would update that reference to the left of root
- Then when you set it to a new node, root would now have a member in it's left field.
However, only option 2 works. Why is that?
Please ignore that it is static if you can, this is merely an example I made to learn how this works. I tried making it not static without using any member variables and it did the same thing.
class binaryTreeNode
{
public binaryTreeNode left;
public binaryTreeNode right;
public int data;
private binaryTreeNode(int data)
{
this.data = data;
}
public binaryTreeNode() {}
public static void insert(binaryTreeNode root, int data)
{
binaryTreeNode newNode = new binaryTreeNode(data);
//option 1
root = root.left;
root = newNode;
//option 2
root.left = newNode;
// in main():
// binaryTreeNode root = new binaryTreeNode();
// root.data = 5;
// binaryTreeNode.insert(root, 3);
// Console.WriteLine(root.left.data);
// null reference on option 1
// outputs properly (int data) on option 2
}
}
CodePudding user response:
You got your third step wrong. Whenever you use = you simply assign the right hand side reference to whatever variable is on the left hand side of the sign. With that in mind you simply change the reference for root from root.left to newNode but root.left would stay unchanged. Therefore the previous line is useless and option 2 is the way to go.
Let's look at some examples to get your way of thinking with references right.
First, let's create a very simple class:
public class Model
{
public int Value;
public Model(int value)
{
this.Value = value;
}
}
Now let's look at some examples:
Example 1:
var model = new Model(3);
Creates a Model instance with value 3 and assigns it to the variable named model.
var reference = model;
Assigns the instance saved in model to reference. They now both point to the same instance.
reference.Value = 2;
Changes the Value property of the instance to 2.
Console.WriteLine(model.Value);
Outputs 2, since the variables reference and model were pointing to the same instance.
Example 2
var model = new Model(3);
Creates a Model instance with value 3 and assigns it to the variable named model.
var model2 = new Model(4);
Creates another Model instance with value 4 and assigns it to the variable named model2.
var reference = model;
Assigns the first instance saved in model to reference. They now both point to the same instance.
reference = model2;
Assigns the second instance saved in model2 to reference. Therefore variable model and reference now do not point at the same instance anymore.
reference.Value = 2;
Changes the Value property of the second instance to 2. The Value property's value of the first instance therefore remains unchanged and continues to be 3.
Console.WriteLine(model.Value);
Outputs 3.
Console.WriteLine(model2.Value);
Outputs 2.
CodePudding user response:
In simple terms for the option one - think about reference as an separate pointer object by itself - this object points to a actual instance of something that you are passing to your method.
So, inside your method, you are assigning an object "root.left" to this reference "object", therefore this reference object now points to new thing.
then again, another assignment - again, root reference points to something new. But the actual thing, the original root object, to which the reference was passed inside the method has not been modified.
Only the reference has been modified and it is now pointing to something else.
Option 2 actually changes something inside the object, o which the passed reference is pointing to - therefore the original actual roor object is modified.
This is a bit of a simplification, but at least should point you in the right direction.
