无法在方法内将对象设置为null

Kar*_*ar 9 c#

在下面的代码中,我试图在测试方法中将节点设置为null.当我这样做时,节点在方法的范围内变为Null,但'parent'不会变为null.我的理解是对象被传递给方法作为参考,并且可以在方法内直接操作.我认为我的概念理解存在问题.您能解释为什么将节点分配给null不会将父节点指定为null.

class Program
{
    static void Main(string[] args)
    {
        Node parent = new Node();
        parent.key = 50;
        parent.left = new Node();
        Test.test(parent);
    }
}

class Test
 {
    public static void test(Node node)
    {
       node.key = 1111;
       node = null;
    }
 }

class Node
    {
        public object key { get; set; }
        public Node left = null;
        public Node right = null;
    }
Run Code Online (Sandbox Code Playgroud)

Bil*_*kil 7

你没有真正传递parentnode通过参考这里.这意味着parent正在复制到函数node中的test值.在这种情况下,该值仅指向一个Node对象.

node.key = 1111按预期工作,因为它使用该值来访问同样parent指向的同一对象.即两者nodeparent包含指向内存中相同位置的值.因此,两者都可以观察到修改.

但是,当你说node = null,你正在nodetest函数内部的变量赋值.这意味着您正在将存储为该特定变量中的值的指针更改为null,这绝不会修改parent仍然指向该Node对象的值.

记住我的业余ASCII艺术,但我认为它有点像这样:

    Test.test(parent);       

         <node object>
           ^       ^ 
           .           .
           .               .
           .                   .
    +------.----+                   .  +-----------+
    |      .    |                       .          |
    |      .    |    (-> copied to)    |    .      |
    |  parent   |                      |    node   |
    +-----------+                      +-----------+
    Program.Main scope                 Test.test scope


    node = null;       

         <node object>
           ^ 
           .
           .
           .
    +------.----+                      +-----------+
    |      .    |                      |           |
    |      .    |                      |           |
    |  parent   |                      | node=null |
    +-----------+                      +-----------+
    Program.Main scope                 Test.test scope
Run Code Online (Sandbox Code Playgroud)

然而,如果你碰巧使用它,public static void test(ref Node node)你可以想到它更像这样:

    Test.test(parent);       

         <node object>
           ^ 
           .
           .
           .
    +------.----+                      +-----------+
    |  parent <============================ node   |
    |           |                      |           |
    |           |                      |           |
    +-----------+                      +-----------+
    Program.Main scope                 Test.test scope


    node = null;       

         <node object>
            Lonely


    +-----------+                      +-----------+
    |  parent <============================ node   |
    |     =     |                      |           |
    |    null   |                      |           |
    +-----------+                      +-----------+
    Program.Main scope                 Test.test scope
Run Code Online (Sandbox Code Playgroud)


uow*_*d01 5

这是因为参数是通过值传递的,所以在您的测试方法中,已经创建了父变量的副本,您只是将变量的副本设置为null。尽管您仍然可以操作对象,因为复制变量指向堆中的对象。

class Program
{
    static void Main(string[] args)
    {
        Foo foo = new Foo();
        SetNull(foo);

        Console.WriteLine(foo.ID);// print 2
    }

    private static void SetNull(Foo foo)
    {
        foo.ID = 2;
        foo = null;
    }
}


class Foo
{
    public int ID { get; set; }
}
Run Code Online (Sandbox Code Playgroud)