-1

我知道这个话题得到了很多回答。我的问题是特定于说或问的方式。

所以我说得对吗,用 class 关键字编写的代码将在托管堆上并且是引用类型,而用 struct 编写的代码将在堆栈上并且是值类型?

4

2 回答 2

6

我以前也是这样想的。然而,我最近与Jon Skeet进行了一次很好的讨论(他可能会提供更多细节),他向我解释说 avalue type也可以保留在堆上。关键是该变量将使用多长时间。如果它是一个短暂的值类型变量,它将只留在堆栈中。但是,如果它被多次使用,框架会将其保留在堆中以节省堆栈空间。

IMO,引用类型和值类型之间的主要区别在于将对象传递给另一个对象或方法。如果它是引用类型,那么您只是在共享它的引用。如果它是一个值类型,那么您正在制作它的副本

关于短 x 长寿命变量的主题,以下是全图:

在桌面 CLR 上的 C# 的 Microsoft 实现中,当值是局部变量或临时值且不是 lambda 或匿名方法的封闭局部变量且方法体不是迭代器块,并且抖动选择不注册该值。

来源:关于值类型的真相(也在评论中)

于 2012-08-20T14:32:02.730 回答
0

引用类型的任何存储位置(局部变量、参数、类字段、结构字段或数组槽)将始终保持null,否则将持有对堆上对象的引用。值类型的存储位置将保存该类型的所有公共和私有字段(原始值类型在内部存储为具有一个字段的结构,该字段被声明为相同的原始类型;一点编译器魔术是用于识别何时必须使用特殊情况代码来处理该类型)。对于每个值类型,都有一个对应的具有相同成员的堆对象类型;尝试将值类型存储在引用类型存储位置将创建适当堆类型的新堆对象,将值类型字段的内容复制到新对象的内容,并存储对该新对象的引用在请求的存储位置。这个过程称为“装箱”。它' 可以将装箱堆对象字段的内容复制到值类型存储位置的内容,这个过程称为“拆箱”。请注意,因为装箱值类型是使用引用类型存储位置访问的,所以它们的行为类似于引用类型而不是类类型。C# 试图假装值类型存储位置的类型和装箱值类型实例的类型是相同的类型,但是这两种类型的行为有些不同;假装它们相同只会增加混乱。C# 试图假装值类型存储位置的类型和装箱值类型实例的类型是相同的类型,但是这两种类型的行为有些不同;假装它们相同只会增加混乱。C# 试图假装值类型存储位置的类型和装箱值类型实例的类型是相同的类型,但是这两种类型的行为有些不同;假装它们相同只会增加混乱。

于 2012-08-20T21:24:58.043 回答