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

时间:2014-02-20 13:01:49

标签: 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

        }


    }
}

当我运行funcChange时,foo从1 Jack更改为2 Inga

当我运行funcNull时,即使我在2 Inga中使用null foo,foo也会保留funcNull

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

如果是这样,那么为什么当我在funcChange上运行foo时,其内容正在发生变化,但是当我运行时 funcNullfoo实例仍然指向2 Inga

非常感谢

4 个答案:

答案 0 :(得分:7)

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

funcChange(Foo bar)

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

funcNull

bar = null;

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

答案 1 :(得分:2)

你的方法应该是

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

并称之为:

        funcNull(ref foo);

答案 2 :(得分:0)

From my understanding , C# passing objects by value (I'm not referring to out or ref !!!) .

并非所有类对象都是引用类型 但是你不应该将passing by reference的概念与引用类型的概念混淆。 如果您声明这样的方法,您应该能够更改基础参数变量

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

答案 3 :(得分:0)

我试过了;

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



foo = funcNull(foo);

当我运行该程序时,会出现运行时错误,指出当我尝试写入其值时foo不存在。 所以这种方法有效。