繁体   English   中英

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

[英]Why can't I instantiate an object in a function

所以基本上我有一个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;
        }
    }

一切都按我的方法预期进行,但回到主目录,我的对象根仍然为null。 我感到困惑的原因是我给了我的方法一个参考,因此它应该将地址的值修改为我要分配的新空间。

我认为我可以通过返回NodeTree来解决问题,但是有没有一种方法可以使用void返回类型呢?

您需要定义要通过引用传递的参数,以便修改原始值(请注意ref关键字):

public static void InsertValueIt(ref NodeTree root, int val) {
    ...

同样,在调用方法时,您需要使用ref标记参数:

Algo.InsertValueIt(ref root, 8);

...否则,您只能在该功能中修改本地副本。

将引用类型传递给方法时会发生什么?
声明为引用类型的变量保存该类型的实例已分配到的内存地址(调用代码中的 )。 此地址的值被复制到在堆栈上为调用的方法创建的新变量( InsertValueIt )。 通过新变量使用该地址,您将能够更改实例的每个公共属性或调用任何方法(前提是所传递的地址不为null)。

如果在此局部变量上调用new会发生什么?
在堆上为该类型分配一个新的内存块,调用构造函数初始化所有内容,并将该块的内存地址存储在InsertValueIt内部的LOCAL变量中。

原始更改(调用代码的根)不受此更改的影响。 (仍为null)。 使用ref关键字会使此“问题”消失,但是我建议使用一种创建Node并将其返回给调用方法的方法。

如果您想更深入地理解该主题,我建议您阅读以下两篇文章:

C#概念: Joseph Albahari的 值类型与引用类型
Jon Skeet的 C#中传递参数

您在InsertValueIt中分配的根值未在任何执行路径中使用,因此应在参数声明中添加ref关键字。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM