将obejct传递给函数并赋值为null,不会更改Main()中的对象

JAN*_*JAN -2 c# function object pass-by-value

考虑以下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Foo
    {
        public int x { get; set; }
        public String y { get; set; }

        public Foo()
        {
            this.x = 1;
            this.y = "Jack";
        }
    }

    class Testing
    {
        public static void funcChange(Foo bar)
        {
            bar.x = 2;
            bar.y = "Inga";
        }

        public static void funcNull(Foo bar)
        {
            bar = null;
        }

        public static void Main()
        {
            Foo foo = new Foo();
            Foo foo2 = foo;

            // let's change foo 
            Console.WriteLine("foo before:" + foo.x + " " + foo.y);  // 1 Jack
            funcChange(foo);
            Console.WriteLine("foo after:" + foo.x + " " + foo.y);  // 2 Inga

            // let's null the foo object
            Console.WriteLine("foo before:" + foo.x + " " + foo.y);  // 2 Inga
            funcNull(foo);
            Console.WriteLine("foo after:" + foo.x + " " + foo.y);  // 2 Inga

        }


    }
}
Run Code Online (Sandbox Code Playgroud)

当我运行funcChange,然后从foo的变化1 Jack2 Inga.

当我跑funcNull,然后foo保持2 Inga甚至在我null foo后funcNull.

根据我的理解,C#按值传递对象(我不是指outref!!!).

如果是这样,那么为什么当我继续运行funcChangefoo,它的内容正在改变,但是当我运行时 funcNull,foo实例仍然指向2 Inga

非常感激

Lee*_*Lee 7

默认情况下,C#会传递值,但是

funcChange(Foo bar)
Run Code Online (Sandbox Code Playgroud)

bar是对类型对象的引用Foo.此引用是输入参数的副本,但它引用托管堆上的同一对象.这就是你可以改变bar的原因funcChange.

funcNull,

bar = null;
Run Code Online (Sandbox Code Playgroud)

将局部变量设置bar为null.由于bar是输入参数的副本,因此它不会影响foo调用者.