簡體   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