2011-08-07 112 views

回答

1

严格地说,它取决于代码的位置。

如果代码是常规函数/方法,它将只影响堆栈。对堆没有任何影响,因为尚未构建MyClass对象。

假设MyClass是一个类(即引用类型),声明将在栈上保留足够的空间来容纳对MyClass对象的引用。

这两个声明略有不同 - 第一个声明没有被初始化,所以任何尝试访问oMyClass1之前它被设置为某些东西会给编译器错误。第二个是初始化的,所以你不会遇到编译器错误[虽然如果你在设置它引用一个实际的对象之前访问了oMyClass2的方法或属性,你会得到一个运行时错误,与oMyClass2 = new MyClass();]。

如果代码是一个类声明中:

class Fred { 
    MyClass oMyClass1; 
    MyClass oMyClass2 = null; 
} 

那么它只会在Fred构造函数中执行。在构造函数被调用之前,空间(对于Fred对象,包括两个MyClass引用的空间)已经在堆上分配了。这两行代码实际上不起作用,因为空格已经被初始化为空。

如果它在一个结构声明内,只会在堆栈上(如果结构是本地的)或全局变量内存(如果结构是静态的)产生相似效果。 [虽然,公平地说,我有点不确定在C#中静态分配的位置 - 我只是假设它以类似于C++的方式完成]

+0

正如我已经在一个现在被删除的答案中所说的,不是类成员的值类型的实例*并不总是存储在堆栈中*。如果它们被lambda表达式或迭代器块捕获,它们将被存储在堆上。 –

+0

引用只会在堆栈上分配,如果它们是本地人。如果他们是班级成员,他们将会堆积如山。 –

+0

@Frédéric值得详细说明的是,如果他们被拉姆达捕获,他们不再是“本地人”。它们将被转换为对闭包类(即包装对象)的属性的引用。闭包坐在堆上。 –

3

我的疑问是如何将上述两行影响内存(堆栈&堆)。

信息不足,两种可能性:

  1. 他们是局部变量。在这种情况下,这两行在堆栈上(无论何时执行该方法多长时间)进行2次相同的分配(参考,总是32/64位)。在堆上没有分配。

  2. 它们是类或结构中的字段。在这种情况下,这两行分配创建时实例中引用的大小。该实例可以在堆栈上(当它们是struct成员时)或堆(类成员)上分配。

+0

+1编辑之后,在点2中区分结构和类。 –