【发布时间】:2014-05-11 18:08:21
【问题描述】:
我一直在阅读 MSDN 上的一些教程,以了解 C#、ref 和 out 中的传递引用,我遇到了以下代码示例:
using System;
class TheClass
{
public int x;
}
struct TheStruct
{
public int x;
}
class TestClass
{
public static void structtaker(TheStruct s)
{
s.x = 5;
}
public static void classtaker(TheClass c)
{
c.x = 5;
}
public static void Main()
{
TheStruct a = new TheStruct();
TheClass b = new TheClass();
a.x = 1;
b.x = 1;
structtaker(a);
classtaker(b);
Console.WriteLine("a.x = {0}", a.x); //prints 1
Console.WriteLine("b.x = {0}", b.x); //prints 5
}
}
教程中对此的注释:
这个例子展示了当一个结构被传递给一个方法时,一个 结构体被传递,但是当一个类实例被传递时,一个引用 已通过。
我完全理解,但我的问题是,如果在 C# 中将引用传递给参数,为什么他们需要ref,如下例所示:
void tearDown(ref myClass a)
{
a = null;
}
MyClass b = new MyClass();
this.tearDown(ref b);
assert(b == null);
//b is null
???我认为 C# 在 C 中是相同的——按值传递。
【问题讨论】:
-
仅仅因为它是引用类型,并不意味着它是通过引用传递的。除非您明确使用
ref,否则按值传递。 -
@JeroenVannevel 是的,默认情况下是按值传递的,但是传递的值本身就是引用类型的引用。
-
MyClass b = new MyClass();部分创建 2 块内存:引用变量b和堆上的匿名实例。引用变量的行为与值类型完全一样(例如int)。 -
Jeroen,不,先生,这不正确。对象通过引用自动传递。要对其进行测试,只需将可变对象(例如字符串列表)作为参数传递给方法。在方法的列表中添加一个项目。然后检查方法之外的列表,您会看到列表已被修改。这仅在通过引用传递对象时发生。引用类型(即所有对象)自动通过引用传递。
-
当您删除
ref时,您的assert(b == null);将失败。 TearDown() 需要通过引用来引用。
标签: c#