最好用一个例子来说明这一点:
public class C { public int P { get; set; } }
public class X
{
static void M(C c1, C c2, ref C c3, ref C c4)
{
c1.P = 11;
c2 = new C() { P = 12 };
c3.P = 13;
c4 = new C() { P = 14 };
}
static void Main()
{
C q1 = new C() { P = 1 };
C q2 = new C() { P = 2 };
C q3 = new C() { P = 3 };
C q4 = new C() { P = 4 };
M(q1, q2, ref q3, ref q4);
Console.WriteLine(q1.P);
Console.WriteLine(q2.P);
Console.WriteLine(q3.P);
Console.WriteLine(q4.P);
}
}
怎么了?
q1 和 c1 指的是同一个对象,但是是不同的变量。变异 c1.P 变异 q1.P 因为两个变量都引用同一个对象,所以 q1 现在是 11。
q2 和 c2 指的是同一个对象,但是是不同的变量。变异 c2 不会变异 q2 因为 c2 和 q2 是不同的变量;改变一个不会改变另一个。q2 保持 2,新对象丢失。
q3 和 c3 是同一个变量的两个名称,因此指的是同一个对象。当您更改 c3.P 时,它会自动更改 q3.P,因为它们是同一事物的两个名称。
q4 和 c4 是同一个变量的两个名称,因此变异 q4 也会变异 c4。
那有意义吗?
不幸的是,“为此变量创建别名”的关键字是“ref”。如果它是“别名”,它会更清楚。
回答你的第二个问题:不,这不会产生引用链。让我们做一个更清楚的例子:
...
int c1 = 123;
M(ref c1);
...
void M1(ref int q1) { M2(ref q1); }
void M2(ref int q2) { M2(ref q2); }
这表示 c1 和 q1 是同一个变量的不同名称,而 q1 和 q2 是同一个变量的不同名称,因此 c1、q1 和 q2 都是彼此的别名。C# 中从来没有像 C++ 中那样的“对变量的引用”。