如果我们把Go方法改成:
public void Go()
{
MyInt x = new MyInt();
x.MyValue = 2;
DoSomething(x);
Console.WriteLine(x.MyValue.ToString());
}
public void DoSomething(MyInt pValue)
{
pValue.MyValue = 12345;
}
{
MyInt x = new MyInt();
x.MyValue = 2;
DoSomething(x);
Console.WriteLine(x.MyValue.ToString());
}
public void DoSomething(MyInt pValue)
{
pValue.MyValue = 12345;
}
这时情形如下图:

开始调用Go时变量x压栈
调用DoSomething时参数pValue压栈
x的值(MyInt在栈中的地址)被复制给pValue
这样就能解释为什么我们改变作为引用类型属性的值类型MyValue时,结果得到的是改变以后的12345了。
有意思的是,当我们使用引用传递一个引用类型的时候,会发生什么呢?
试试吧。假设有下列引用类型:
public class Thing
{
}
public class Animal:Thing
{
public int Weight;
}
public class Vegetable:Thing
{
public int Length;
}
{
}
public class Animal:Thing
{
public int Weight;
}
public class Vegetable:Thing
{
public int Length;
}
开始执行Go方法,这时x指针存在于栈中
public void Go()
{
Thing x = new Animal();
Switcharoo(ref x);
Console.WriteLine("x is Animal : " + (x is Animal).ToString());
Console.WriteLine("x is Vegetable : " + (x is Vegetable).ToString());
}
public void Switcharoo(ref Thing pValue)
{
pValue = new Vegetable();
}
{
Thing x = new Animal();
Switcharoo(ref x);
Console.WriteLine("x is Animal : " + (x is Animal).ToString());
Console.WriteLine("x is Vegetable : " + (x is Vegetable).ToString());
}
public void Switcharoo(ref Thing pValue)
{
pValue = new Vegetable();
}
结果变量x变成了Vegetable。
x is Animal : False
x is Vegetable : True
x is Vegetable : True
看看都怎么回事:

开始执行Go方法,这时x指针存在于栈中
Animal存在于堆中
执行Switcharoo方法,pValue存在于栈中,同时指向x(引用传递)

Vegetable在堆中分配(new Vegetable)
pValue指向x,因此改变pValue的内容实际上是去改变x指向的内容,因此x收pValue的影响指向了Vegetable
如果我们不通过引用传递,那么我们将得到相反的结果,x仍然是Animal。(为什么?可以自个儿去画个图哈)
In Conclusion
接下来的章节里,我们会介绍栈里头的引用变量是怎么回事,以及如何克服复制对象时会遇到的一些麻烦。