【问题标题】:Passing obejct to function and assigning null , won't change the object in Main()将对象传递给函数并分配 null ,不会更改 Main() 中的对象
【发布时间】:2014-03-21 10:38:18
【问题描述】:

考虑这段代码:

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 时,即使我将 funcNull 中的 foo 设为 null 之后,foo 也会保持 2 Inga

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

如果是这样,那为什么当我在 foo 上运行 funcChange 时,它的内容正在改变,但是当我运行时 funcNullfoo 实例仍然指向 2 Inga 吗?

非常感谢

【问题讨论】:

标签: c# function object pass-by-value


【解决方案1】:

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;
        }

【讨论】:

  • 这不会改变 object - 它会改变调用代码中用于参数的 variable。区分变量和对象很重要。
【解决方案2】:

你的方法应该是

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

然后这样称呼它:

        funcNull(ref foo);

【讨论】:

    【解决方案3】:

    我试过了;

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

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

    【讨论】:

      【解决方案4】:

      默认情况下,C# 确实按值传递,但是在

      funcChange(Foo bar)
      

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

      funcNull

      bar = null;
      

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

      【讨论】:

        猜你喜欢
        • 2014-06-05
        • 1970-01-01
        • 2020-08-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-01
        • 2015-08-30
        • 2011-12-07
        相关资源
        最近更新 更多