【发布时间】:2011-07-30 15:27:35
【问题描述】:
当operator new() 与引用类型一起使用时,实例的空间分配在堆上,引用变量本身放在堆栈上。除此之外,在堆上分配的引用类型实例中的所有内容都被清零。
例如这里是一个类:
class Person
{
public int id;
public string name;
}
在以下代码中:
class PersonDemo
{
static void Main()
{
Person p = new Person();
Console.WriteLine("id: {0} name: {1}", p.id, p.name);
}
}
p 变量在堆栈上,Person 的创建实例(它的所有成员)在堆上。 p.id 将是 0 和 p.name 将是 null。
之所以会出现这种情况,是因为在堆上分配的所有内容都被清零了。
现在我感到困惑的是,如果我使用带有 new 运算符的值类型。例如,考虑以下结构:
struct Date
{
public int year;
public int month;
public int day;
}
class DateDemo
{
static void Main()
{
Date someDate;
someDate= new Date();
Console.WriteLine("someDate is: {0}/{1}/{2}",
someDate.month, someDate.day, someDate.year);
}
}
现在我想知道 main 中的以下几行是做什么的:
Date someDate;
someDate= new Date();
在第一行someDate 变量在堆栈上分配。正好是 12 个字节。
我的问题是第二行发生了什么? operator new() 是做什么的?它只是将Date 结构的成员清零还是在堆上分配空间?一方面,我不希望new 在堆上分配空间,当然因为在第一行中,内存已经在堆栈上分配给结构实例。另一方面,我希望new 在堆上分配空间并返回该空间的地址,因为这是new 应该做的。
也许这是因为我来自 C++ 背景。
尽管如此,如果答案是:“当new 与值类型一起使用时,它只会将对象的成员清零”,那么new 运算符的含义有点不一致,因为:
- 将
new与值类型一起使用时,它只会将堆栈上的对象成员清零 - 将
new与引用类型一起使用时,它会在堆上为实例分配内存并将其成员清零
提前致谢,
干杯
【问题讨论】:
-
除了链接的问题之外,您可能还想阅读这篇博文:msmvps.com/blogs/jon_skeet/archive/2008/12/10/… - 我以为我最近看过 Eric Lippert 的一篇文章,但现在找不到了。
-
@Jon 谢谢。找了一阵子,没找到。可能是因为您所链接的问题的措辞方式与查找时很容易找到的方式不同?
-
确实 - 作为答案,它变得比原来建议的问题更复杂:)
-
上面的博客链接坏了,这是新的url:codeblog.jonskeet.uk/2008/12/10/…
标签: c# .net value-type reference-type