深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第四节 参数传递对堆栈的影响 2

10 篇文章 0 订阅
10 篇文章 0 订阅

参数传递对堆栈的影响

导航

前言


虽然在.Net Framework 中我们不必考虑内在管理和垃圾回收(GC),但是为了优化应用程序性能我们始终需要了解内存管理和垃圾回收(GC)。另外,了解内存管理可以帮助我们理解在每一个程序中定义的每一个变量是怎样工作的。

简介


继续上篇未完成的“参数传递对堆栈的影响”。

引用类型传递


传递引用类型跟上一节所示例中用引用的方式传递值类型相似。

如果使用引用类型(原文可能笔误,写的是值类型):
public class MyInt
           {
               public int MyValue;
           }

然后调用Go()方法,MyInt会被放到堆里因为它是一个引用类型。
public void Go()
          {
             MyInt x = new MyInt();              
          }



如果执行下面代码中的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。
  2. 执行行到DoSomething(),栈分配一块内在空间给pValue。
  3. x的值是堆中MyInt对应在栈里的内存地址,复制x给pValue。
因此,我们用pValue改变MyInt的MyValue的值时,x最终也会获得这个改变的值"12345“。
如果我们用引用的方式传递一个引用类型变量呢?

用引用的方式传递引用类型

我们有一个类Thing, 类 Animal和Vegetables衍生于Thing:
public class Thing
           {
           }
 
           public class Animal:Thing
           {
               public int Weight;
           }
 
           public class Vegetable:Thing
           {
               public int Length;
           }

执行下面的Go()方法:
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。
  2. 堆分配一块内存空间给Animal。
  3. 开始执行Switcharoo()方法,栈分配一块内存空间给pValue并指向x。

  4. 栈分配一块内存空间给Vegetable。
  5. pValue改变了x的值使其指向Vegetable的内在地址。
如果我们不是用ref传递的,打印结果正相反。


总结


我们已经演示了参数传递是怎么在内在中处理的。在接下来的文章里,存储在栈中的引用变量会产生什么情况以及怎么解决对象复制带来的问题。


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




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值