C#引用类型问题

时间:2012-12-06 17:41:19

标签: c# pass-by-reference

 public class TreeNode
{
    public TreeNode Left;
    public TreeNode Right;
    public int Data { get; set; }

    public TreeNode(int data)
    {
        Left = null;
        Right = null;
        Data = data;
    }
}



   public class BinarySearchTree
{
    private TreeNode _root;

    public BinarySearchTree()
    {
        _root = null;
    }

    public void Insert(int data)
    {
        TreeNode tempNode = null;

        Insert(_root, tempNode);
    } 

    private void Insert(TreeNode treeNode, TreeNode newNode)
    {
        newNode = new TreeNode(3);
        treeNode = new TreeNode(4);
   }

在此示例中,public void Insert(int data)方法基本上只调用private方法,并在public void Insert(int data)方法的末尾添加了一个断点。

并且注意_root仍然为空,tempNode为4.我不明白为什么?有人可以解释一下吗?

3 个答案:

答案 0 :(得分:3)

要按引用传递类,请使用ref关键字:

private void Insert(ref TreeNode treeNode, ref TreeNode newNode)
{
    newNode = new TreeNode(3);
    treeNode = new TreeNode(4);
}

在原始方法中,只传递副本对类的引用,它们不会通过引用传递。因此,如果您正在执行new,那么您只是替换类引用的本地副本,但调用方法仍保留原始引用值。因此,新创建的值不会返回给调用者。

更改Insert(data)方法(没有ref关键字编译器会给您一个错误):

public void Insert(int data)
{
    TreeNode tempNode = null;
    Insert(ref _root, ref tempNode);
} 

这实际上是一个编译器要求,只是为了确保调用者知道在方法调用之后传递的对象可能被其他对象替换。

您可能还想了解out关键字。虽然ref参数应在调用之前初始化,但out参数应在方法内初始化。

答案 1 :(得分:0)

您正在传递引用类型,但它实际上传递了引用的副本。更新该副本不会更新原始文件。

要解决此问题,要么让方法返回新值。或者你可以修改你的函数来使用参数。

private void Insert(out TreeNode treeNode, out TreeNode newNode)
{
    newNode = new TreeNode(3);
    treeNode = new TreeNode(4);
}

答案 2 :(得分:0)

查看参数的outref修饰符。例如,您可以

private void Insert(ref TreeNode treeNode, TreeNode newNode)