代码改变世界

.net垃圾回收学习【C#中的stack和Hepa】【续2】

2011-08-21 22:35  一一九九  阅读(363)  评论(0编辑  收藏  举报

From http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory2B01142006125918PM/csharp_memory2B.aspx

记录学习。

Passing Reference Types.

     传递引用类型的参数和之前通过引用传递至类型的参数有点类似。

如下代码:

public class MyInt
{
   public int MyValue;
}

当调用Go方法的时候,由于MyInt是一个引用类型,所以在heap创建

public void Go()
{
   MyInt x = new MyInt();
}

heapvsstack2-7

当我们执行如下代码的时候:

          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;
           }

stack和heap上的情况如下:

heapvsstack2-8

这个过程中发生了如下的事情:

  • 开始调用GO方法的时候,X变量进入stack中。
  • 开始调用DoSometing方法的时候,参数pValue进入Stack中。
  • x的值(在stack上的MyInt的地址)被copy给了pValue.

所以当修改heap上的值的时候,x的值也发生了变化。

那么,如果我们通过引用传递一个引用类型会发生什么呢?

假如我们有如下类:

           public class Thing
           {
           }

           public class Animal:Thing
           {
               public int Weight;
           }

 
           public class Vegetable:Thing
           {
               public int Length;
           }

当我们执行如下的方法的时候:

          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 is Animal    :   False
x is Vegetable :   True

让我们看一下发生了什么:

heapvsstack2-9

1. 开始调用Go方法的时候,参数x进入stack中
2.  Animal在heap上创建
3. 开始调用Switcharoo()方法,pValue进入Stack,并且指向了x。

heapvsstack2-10

4. Vegetable在heap创建
5.  x的值被修改为Vegetable的地址。

todo:  考虑一下字符串的内存分配和处理,为什么系统中的代码都会添加ref参数。