所以基本上我有一个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; }
}
在我的主要内容中,我想做一些像
这样的事情NodeTree root = null;
Algo.InsertValueIt(root, 8);
其中InsertValueIt()是我的静态类Algo中的一个方法:
public static void InsertValueIt(NodeTree root, int val)
{
var newNode = new NodeTree(val, null, null);
if (root == null)
{
root = newNode;
}
}
在我的方法中,一切都按预期工作,但回到我的主要,我的对象根仍然是空的。 我感到困惑的原因是我给我的方法一个引用,所以它应该将地址的值修改为我分配的新空间。
我认为我可以通过返回NodeTree来解决我的问题,但有没有办法用void返回类型来做?
答案 0 :(得分:5)
您需要定义要通过引用传递的参数,以便修改原始值(请注意ref
关键字):
public static void InsertValueIt(ref NodeTree root, int val) {
...
同样在调用方法时,您需要使用ref
标记参数:
Algo.InsertValueIt(ref root, 8);
...否则您只修改该功能中的本地副本。
答案 1 :(得分:2)
将引用类型传递给方法时会发生什么?
声明为引用类型的变量保存已分配类型实例的内存地址(调用代码中的 root )。此地址的值将复制到在堆栈上为被调用方法创建的新变量(InsertValueIt
中的根)。通过新变量使用该地址,您将能够更改实例的每个公共属性或调用任何方法(假设传递的地址不为null)。
如果您在此本地变量上调用new,会发生什么?
在堆的类型上分配新的内存块,调用构造函数来初始化所有内容,并且此块的内存地址存储在InsertValueIt
内的LOCAL变量中。
您原来的(调用代码中的根)不受此更改的影响。 (仍然保持为空)。使用ref关键字可以解决这个问题'消失,但我建议使用一个创建Node的方法,然后将其返回给调用方法。
如果你想更深入地理解这个主题,我推荐这两篇文章:
来自 Joseph Albahari 的C#Concepts: Value Types vs Reference Types 来自 Jon Skeet
的Parameter Passing in C#答案 2 :(得分:0)
在InsertValueIt中分配的根值未在任何执行路径中使用,因此您应在参数声明中添加ref关键字