我知道这是一个老问题,但在我看来,没有任何答案给出了一个好的直接原因。
在这种情况下,您不需要使用 ref
,以下是原因。考虑这个函数:
void Foo(MyClass a1, ref MyClass a2, out MyClass b1, int c1, MyStruct d1, ref MyStruct d2)
{
}
现在将此函数称为:
MyClass a = new MyClass();
MyClass b = null
int c = 3;
MyStruct d = new MyStruct();
Foo(a, ref a, b, c, d, ref d);
以下是该函数内部的内容:
void Foo(MyClass a1, ref MyClass a2,
out MyClass b1,
int c1,
MyStruct d1, ref MyStruct d2)
{
a1 is a copy in memory of the pointer to the instantiated class a;
a2 is the pointer to the instantiated class a;
b1 is the pointer to b, but has the additional check of having to be set within this function - and cannot be used before being set;
c1 is a copy in memory of the variable c;
d1 is a copy in memory of the struct d;
d2 is the struct d;
}
重要的事情需要注意:
- 将
a1
设置为 null
不会将 a
设置为 null
。
- 将
a2
设置为 null
会将 a
设置为 null
。
- 必须设置
b1
。
- 将
c1
设置为 null
不会改变 c
。
- 将
d1
设置为 null
不会改变 d
。
- 将
d2
设置为其他值会改变 d
。
这样可以实现一些奇怪的操作,例如:
void Foo(MyClass x, ref MyClass y)
{
x = null;
y.Bar("hi");
}
被称为:
MyClass a = new MyClass();
Foo(a, ref a);
您正在使用一个类,因此您的情况更像是函数调用中的变量
a1
。这意味着
ref
并不是严格必需的。
Jon Skeet的文章对您帮助不大,因为他的
IntHolder
示例是一个
struct
而不是
class
。
Struct
是值类型,就像
int
一样,必须以相同的方式处理。
ref
,所以最终我得到了正确的答案。 - NefzenFoo
想象成持有第9,421个被创建的对象的引用,并称其为“Object #9421”会很有帮助。因此,语句Foo.Bar()
的意思是“在对象#9421上执行Bar
”。语句Boz.Bar(Foo)
告诉Bar
它感兴趣的对象是#9421,但不允许Bar
更改Foo
- 它仍将保持“Object #9421”。相比之下,Boz.Bar(ref Foo)
则允许Bar
更改Foo
以持有“Object #24601”,如果它选择这样做的话。 - supercat