考虑以下代码:
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#按值传递对象(我不是指out
或ref
!!!)。
如果是这样,那么为什么当我在funcChange
上运行foo
时,其内容正在发生变化,但是当我运行时
funcNull
,foo
实例仍然指向2 Inga
?
非常感谢
答案 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不存在。 所以这种方法有效。