这里有几个不同的东西:
- 对象存储在堆中,请暂时忽略它们;
First
和Second
中存储的是对对象引用;
Main
中有两个变量;
Swap
中有两个参数;
现在,重要的事情是"引用类型/引用"和"按引用传递"之间的区别。它们完全无关。
在下面这行代码中:
Swap(First, Second);
你将两个变量的值传递给了“Swap”函数。在这种情况下,“First” / “Second”的值是指向封装对象的引用。请注意,保留了HTML标签。
接下来:
private static void Swap(object First, object Second)
{
object temp = First;
First = Second;
Second = temp;
}
在这里,你交换了两个本地参数的值,但是它们完全独立于任何其他事情。如果我们想让调用者看到值的改变(即重新赋值),我们需要通过引用传递:
private static void Swap(ref object First, ref object Second)
{
object temp = First;
First = Second;
Second = temp;
}
现在,First
的值不再是对装箱对象的引用;它是对装箱对象的引用的引用。在调用者处,我们使用:
Swap(ref First,ref Second);
这意味着要传递变量First
的引用,而不是值。
请注意,我说过您可以忘记存在对象这一事实吗?如果我们使用以下代码,所有内容都完全相同:
int x = 1, y = 2;
Swap(ref x, ref y);
void Swap(ref int a, ref int b) {
var tmp = a; a = b; b = tmp;
}
唯一的区别在于,x
的 值 为 1 等等,而 ref x
是对变量 x 的引用。在按引用传递时,引用类型与值类型完全无关;唯一重要的是理解默认情况下传递变量的 值,其中变量的 值 是 1
(等等)或“对象的引用”。无论哪种方式,逻辑都是相同的。