为什么我不能在函数中实例化对象

本文关键字:实例化 对象 函数 不能 为什么 | 更新日期: 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 关键字