为什么我不能在函数中实例化对象
本文关键字:实例化 对象 函数 不能 为什么 | 更新日期: 2023-09-27 18:34:09
所以基本上我有一个类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 返回类型来做到这一点?
你需要定义通过引用传递的参数,以便修改原始值(注意ref
关键字(:
public static void InsertValueIt(ref NodeTree root, int val) {
...
同样在调用该方法时,您需要用 ref
标记参数:
Algo.InsertValueIt(ref root, 8);
。否则,您只能在该函数中修改本地副本。
将引用类型传递给方法时会发生什么情况?
声明为引用类型的变量保存已分配类型实例的内存地址(调用代码中的根(。此地址的值将复制到堆栈上为被调用方法创建的新变量(InsertValueIt
中的根(。通过新变量使用该地址,您将能够更改实例的每个公共属性或调用任何方法(前提是传递的地址不为 null(。
如果在此局部变量上调用 new,现在会发生什么?
在堆上为类型分配一个新的内存块,调用构造函数来初始化所有内容,并且该块的内存地址存储在InsertValueIt
内的 LOCAL 变量中。
您的原始版本(调用代码中的根(不受此更改的影响。(仍为空(。使用 ref 关键字会使这个"问题"消失,但我建议使用创建 Node 并将其返回到调用方法的方法。
如果你想更深入地了解这个主题,我推荐这两篇文章:
C#概念:值类型与引用类型 来自 Joseph Albahari
来自 Jon Skeet 的 C# 中的参数传递
在 InsertValueIt 中分配的根值不在任何执行路径中使用,因此您应该在参数声明中添加 ref 关键字