我正在阅读 Jon Skeet 的书评,他正在研究Head First C#的许多不准确之处。
其中一个引起了我的注意:
[在错误部分下] 声称结构始终存在于堆栈中。
在什么情况下结构不会存在于堆栈中?这与我认为我对结构的了解相反。
我正在阅读 Jon Skeet 的书评,他正在研究Head First C#的许多不准确之处。
其中一个引起了我的注意:
[在错误部分下] 声称结构始终存在于堆栈中。
在什么情况下结构不会存在于堆栈中?这与我认为我对结构的了解相反。
一个常见的例子是结构是在堆中分配的对象的成员。这个问题在这里有很多额外的细节。.Net 中的结构和类有什么区别?
每当他们是班级的一个领域
不寻常的例子:
a:当捕获值类型变量时:
int i = 2;
Action action = delegate {i++;}
action();
Console.WriteLine(i);
这被编译成更像:
class Foo {
public int i;
public void Bar() {i++;}
}
...
Foo foo = new Foo();
foo.i = 2;
Action action = foo.Bar;
action();
Console.WriteLine(foo.i);
b:当在迭代器块中使用值类型变量时:
IEnumerable<int> GetValues() {
for(int i = 0 ; i < 5 ; i++) yield return i;
}
(编译器生成状态机来表示迭代器,其中所有的局部变量(如i
)都是字段)
就像1800 INFORMATION 的答案示例:
public class Foo
{
int x;
public Foo(int y)
{
x = y;
}
}
...
Foo foo = new Foo(10);
现在,构造函数执行完毕后,值为foo.x
10。foo.x
内存在哪里?在堆上。是什么类型的foo.x
?int
aka System.Int32
,这是一个结构。
关于捕获的变量和装箱等的其他答案也是正确的(在装箱案例中“有点” - 我将添加评论),但这个例子是最简单和最重要的一个,IMO。
其他人已经深入提及
此外:
这本书犯了将类型机制与作用域机制混淆的错误。值类型不是引用类型。当您调用使用它作为参数的方法时,它的数据被复制(没有 ref 或 out)。值类型将存在于方法范围内的堆栈中,而不是像引用对象那样存在于堆中,但这并不意味着它总是存在于堆栈中。
因此,这本书是在用一个用法说明来代替力学说明,并将两者混淆。这不是完全没有根据的说法,但这是错误的。
值类型将保存在其所有者所在的任何地方。
因此,如果它们的作用域是一个方法,它们就会在堆栈中。如果他们的作用域是一个对象,他们将与堆上的对象一起生活。
这样一来,可以很肯定地说,值类型最好保留为不可变的,因为大多数人很难预测按值的值类型机制。