C#引用类型作为另外一个引用类型的成员,如何存储?

pengfei_yang 2012-03-07 11:32:18
已经知道,当引用类型作为其他引用类型的成员时,存储情如下:

1.引用类型对象的数据部分始终存放在堆里。
2.值类型对象和引用类型的引用既可以存在栈里,也可以存在堆里。取决于实际环境。

例如:有一个MyType的引用类型的实例,包含两个成员:一个值类型,一个引用类型。
它的值类型明显要存储在堆里。那么引用类型成员呢?

由1可知,内部的引用类型作为对象的一部分,其引用也保存在对立面。
---------------------------------------------------------------------------
以上总结自《C#图解教程》第三章引用类型与值类型部分
---------------------------------------------------------------------------
建立一个最普通的程序(以VS自动创建的代码为例):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Test2
{
class Program
{
static void Main(string[] args)
{

}
}
}


外层对象基本上都是引用类型(此例中的Program类),按上面的分析,我们无论
自己添加类,还是完善此类,最终对象都是要存储中堆中的。那么栈是不是很少(或者几乎)用不到呢?

----------------------------------------------------------------------------
在《C# 4.0图解教程》24页中,说道栈的作用有三种:

1.某些类型变量的值。
2.程序当前的执行环境。
3.传递给方法的参数。

这三条看着到觉得很熟悉,但有总觉得思路很不清晰。
哪些类型的值?引用类型?
程序当前的执行环境?是要把CLR当做操作系统来理解吗?CLR也要管理多个程序,也需要上下文切换?
传递给方法的参数?这时候不分引用类型和值类型了吗?
---------------------------------------------------------------------------

期待不啬赐教。
...全文
315 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
红色魔术师 2013-08-14
  • 打赏
  • 举报
回复
您好,最近我也想到了这个问题,请看45页,表5-1,最后一个。当在本地变量中存在引用时,则会存储在栈里。值类型也会存储在栈里。所以我的理解是在本地变量中用到的都是在栈里。
qldsrx 2012-03-12
  • 打赏
  • 举报
回复
参考:http://www.cnblogs.com/sealedlove/archive/2009/02/13/1390278.html

点评:看完这篇文章后,想必你应该对什么是堆,什么是栈(也叫堆栈)有了更深的了解了吧。那么你的结论“它的值类型明显要存储在堆里”就是错误的,你再看你自己给的原文“值类型对象和引用类型的引用既可以存在栈里,也可以存在堆里。取决于实际环境。”更说明问题——取决于实际环境。我们实际操作的时候,根本不需要它是存放在何处,因为我们无法直接对堆、栈进行操作(知道了又如何?)。如果你精通.NET,会直接使用IL语言编写代码了,那么你就可以直接对堆、栈进行操作了,那时你就会看到什么时候存在堆里,什么时候存在栈里。
例如:任何函数执行的参数都是先压入栈,引用类型将引用地址先入栈后获取实际数据入栈,然后将函数方法入栈执行的。入栈之前,数据是在堆里面。执行之后,自动出栈。
pengfei_yang 2012-03-12
  • 打赏
  • 举报
回复
“实际环境”,书的上下文(有点就书论书的意思...包涵...)暗示分了两种,一种是普通值类型的情况,一种是值类型包含在一个引用类型中的情况。
我所给出的MyType这个例子,就是后一种。假设MyType如下:

class MyType()
{
int a;
ref b;
}
“它的值类型明显要存储在堆里”,更复杂的环境不考虑,但就本实例,我觉得还是正确的,所以a还是应该存在堆中。

我的问题依然是:既然我们外层基本上都是Class之类的引用类型,那么内部就没有用到栈的机会了....


或者真的是在具体执行的过程中,很复杂,远非这么分析一下这么简单。又看了一遍你说的这句话:

“我们实际操作的时候,根本不需要它是存放在何处,因为我们无法直接对堆、栈进行操作(知道了又如何?)”。

在理。慢慢去理解吧。
pengfei_yang 2012-03-11
  • 打赏
  • 举报
回复
自己顶一下。
pengfei_yang 2012-03-08
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 yxw545061402 的回复:]

我的理解是这样的,可能有错,不过就算错,可能也对你有所启发吧
class a{int b;string c=new c();}
a的实例a1,当说这个a1变量,它在栈中,把它当成4字节的指针理解,但是a1指向的是堆中的对象{int b;string c=new c();},而这个b又是值类型,这里的b变量,也仅仅是指针,但是它指向的是存在栈中的int数据,c就类似a了。所以在这个a实例中存在……
[/Quote]
可能是我没有表达清楚吧。你的意思我明白,我的理解和你是一样的。
我的问题在于,既然我们写的程序基本上都是包含在类(也有其他的)这个引用类型中的,
那么栈是不是很少(或者几乎)用不到呢?
晏子 2012-03-07
  • 打赏
  • 举报
回复
我的理解是这样的,可能有错,不过就算错,可能也对你有所启发吧
class a{int b;string c=new c();}
a的实例a1,当说这个a1变量,它在栈中,把它当成4字节的指针理解,但是a1指向的是堆中的对象{int b;string c=new c();},而这个b又是值类型,这里的b变量,也仅仅是指针,但是它指向的是存在栈中的int数据,c就类似a了。所以在这个a实例中存在栈中的有三个值,a变量,b数据,c变量;存在堆中的有 a对象,c对象
zzzzv0 2012-03-07
  • 打赏
  • 举报
回复
2.值类型对象和引用类型的引用既可以存在栈里,也可以存在堆里。取决于实际环境。

就是因为这些东西一出大括号就没了,所以GC才会自动干活啊

111,126

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧