C# 方法中的对象操作
C# Object manipulation in method
我无法理解对象操作在 C# 方法中的工作原理。我知道当您将对象传递给方法时,传递的是对该对象的引用。考虑到这一点,我认为选项 1 会像这样工作:
- root 变量作为对 root 的引用进入方法
- 当您将它设置为 root.left 时,它会将该引用更新到 root
的左侧
- 然后,当您将其设置为新节点时,root 现在将在其左侧字段中有一个成员。
但是,只有选项 2 有效。这是为什么?
如果可以,请忽略它是静态的,这只是我为了了解其工作原理而制作的示例。我尝试在不使用任何成员变量的情况下使它不是静态的,它做了同样的事情。
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
}
}
选项一的简单术语 - 将引用本身视为一个单独的指针对象 - 此对象指向您传递给方法的某物的实际实例。
因此,在您的方法中,您将对象“root.left”分配给此引用“对象”,因此此引用对象现在指向“root.left”实例。
然后,另一个赋值——再次,根引用指向“newNode”实例。但是实际的东西,在方法内部传递引用的原始根对象并没有被修改。
只有引用已被修改,它现在指向其他内容。
选项 2 实际上更改了传递的引用指向的对象内部的某些内容 - 因此修改了原始的实际根对象。
这有点简化,但至少应该为您指明正确的方向。
你第三步走错了。每当您使用 =
时,您只需将右侧引用分配给符号左侧的任何变量。考虑到这一点,您只需将 root
的引用从 root.left
更改为 newNode
,但 root.left
将保持不变。因此,上一行是无用的,选项 2 是可行的方法。
让我们看一些示例,以正确参考您的思维方式。
首先,让我们创建一个非常简单的 class:
public class Model
{
public int Value;
public Model(int value)
{
this.Value = value;
}
}
现在让我们看一些例子:
Example 1:
var model = new Model(3);
创建一个值为 3
的 Model
实例并将其分配给名为 model
的变量。
var reference = model;
将 model
中保存的实例分配给 reference
。他们现在都指向同一个实例。
reference.Value = 2;
将实例的 Value
属性 更改为 2
。
Console.WriteLine(model.Value);
输出 2
,因为变量 reference
和 model
指向同一个实例。
Example 2
var model = new Model(3);
创建一个值为 3
的 Model
实例并将其分配给名为 model
的变量。
var model2 = new Model(4);
创建另一个 Model
实例,值为 4
并将其分配给名为 model2
的变量。
var reference = model;
将 model
中保存的第一个实例分配给 reference
。他们现在都指向同一个实例。
reference = model2;
将 model2
中保存的第二个实例分配给 reference
。因此变量 model
和 reference
现在 不再指向 同一个实例。
reference.Value = 2;
将第二个实例的 Value
属性 更改为 2
。 Value
属性 的第一个实例的值因此保持不变并继续为 3
.
Console.WriteLine(model.Value);
输出 3
.
Console.WriteLine(model2.Value);
输出 2
.
我无法理解对象操作在 C# 方法中的工作原理。我知道当您将对象传递给方法时,传递的是对该对象的引用。考虑到这一点,我认为选项 1 会像这样工作:
- root 变量作为对 root 的引用进入方法
- 当您将它设置为 root.left 时,它会将该引用更新到 root 的左侧
- 然后,当您将其设置为新节点时,root 现在将在其左侧字段中有一个成员。
但是,只有选项 2 有效。这是为什么?
如果可以,请忽略它是静态的,这只是我为了了解其工作原理而制作的示例。我尝试在不使用任何成员变量的情况下使它不是静态的,它做了同样的事情。
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
}
}
选项一的简单术语 - 将引用本身视为一个单独的指针对象 - 此对象指向您传递给方法的某物的实际实例。
因此,在您的方法中,您将对象“root.left”分配给此引用“对象”,因此此引用对象现在指向“root.left”实例。
然后,另一个赋值——再次,根引用指向“newNode”实例。但是实际的东西,在方法内部传递引用的原始根对象并没有被修改。
只有引用已被修改,它现在指向其他内容。
选项 2 实际上更改了传递的引用指向的对象内部的某些内容 - 因此修改了原始的实际根对象。
这有点简化,但至少应该为您指明正确的方向。
你第三步走错了。每当您使用 =
时,您只需将右侧引用分配给符号左侧的任何变量。考虑到这一点,您只需将 root
的引用从 root.left
更改为 newNode
,但 root.left
将保持不变。因此,上一行是无用的,选项 2 是可行的方法。
让我们看一些示例,以正确参考您的思维方式。
首先,让我们创建一个非常简单的 class:
public class Model
{
public int Value;
public Model(int value)
{
this.Value = value;
}
}
现在让我们看一些例子:
Example 1:
var model = new Model(3);
创建一个值为 3
的 Model
实例并将其分配给名为 model
的变量。
var reference = model;
将 model
中保存的实例分配给 reference
。他们现在都指向同一个实例。
reference.Value = 2;
将实例的 Value
属性 更改为 2
。
Console.WriteLine(model.Value);
输出 2
,因为变量 reference
和 model
指向同一个实例。
Example 2
var model = new Model(3);
创建一个值为 3
的 Model
实例并将其分配给名为 model
的变量。
var model2 = new Model(4);
创建另一个 Model
实例,值为 4
并将其分配给名为 model2
的变量。
var reference = model;
将 model
中保存的第一个实例分配给 reference
。他们现在都指向同一个实例。
reference = model2;
将 model2
中保存的第二个实例分配给 reference
。因此变量 model
和 reference
现在 不再指向 同一个实例。
reference.Value = 2;
将第二个实例的 Value
属性 更改为 2
。 Value
属性 的第一个实例的值因此保持不变并继续为 3
.
Console.WriteLine(model.Value);
输出 3
.
Console.WriteLine(model2.Value);
输出 2
.