技术开发 频道

.Net入门:帮你一次性搞定堆和栈

  如果我们把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;
}

   这时情形如下图:

1

  开始调用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;
}

   开始执行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();
}

         结果变量x变成了Vegetable。

x is Animal    :  False
  x
is Vegetable :   True

       看看都怎么回事:

1


       开始执行Go方法,这时x指针存在于栈中

  Animal存在于堆中

  执行Switcharoo方法,pValue存在于栈中,同时指向x(引用传递)

1

  Vegetable在堆中分配(new Vegetable)

  pValue指向x,因此改变pValue的内容实际上是去改变x指向的内容,因此x收pValue的影响指向了Vegetable

  如果我们不通过引用传递,那么我们将得到相反的结果,x仍然是Animal。(为什么?可以自个儿去画个图哈)

  In Conclusion

  接下来的章节里,我们会介绍栈里头的引用变量是怎么回事,以及如何克服复制对象时会遇到的一些麻烦。

0
相关文章