C# 堆栈和堆内存效应?
在以下代码中:C# 堆栈和堆内存效应?,c#,.net,memory-management,stack,heap,C#,.net,Memory Management,Stack,Heap,在以下代码中: MyClass oMyClass1; MyClass oMyClass2 = null; 我的疑问是,上述两行将如何影响内存(堆栈和堆) 是否将在堆栈中创建引用?严格来说,这取决于代码所在的位置 如果代码位于常规函数/方法中,则只会影响堆栈。这对堆没有影响,因为还没有构造MyClass对象 假设MyClass是一个类(即引用类型),则每个声明都会在堆栈上保留足够的空间来保存对MyClass对象的引用 这两个声明稍有不同——第一个声明尚未初始化,因此在将其设置为某个值之前尝试访问
MyClass oMyClass1;
MyClass oMyClass2 = null;
我的疑问是,上述两行将如何影响内存(堆栈和堆)
是否将在堆栈中创建引用?严格来说,这取决于代码所在的位置 如果代码位于常规函数/方法中,则只会影响堆栈。这对堆没有影响,因为还没有构造MyClass对象 假设MyClass是一个类(即引用类型),则每个声明都会在堆栈上保留足够的空间来保存对MyClass对象的引用 这两个声明稍有不同——第一个声明尚未初始化,因此在将其设置为某个值之前尝试访问myclass1将导致编译器错误。第二个是初始化的,因此不会出现编译器错误[尽管如果在将omiclass2的方法或属性设置为引用实际对象之前访问它,会出现运行时错误,例如,使用omiclass2=new MyClass();] 如果代码位于类声明中:
class Fred {
MyClass oMyClass1;
MyClass oMyClass2 = null;
}
然后,它将仅在Fred构造函数期间执行。在调用构造函数之前,堆上已经分配了空间(用于Fred对象,包括用于两个MyClass引用的空间)。这两行代码实际上没有任何效果,因为空格已经初始化为null
如果它位于结构声明内部,则效果类似,仅在堆栈(如果结构是本地的)或全局变量内存(如果结构是静态的)上。[虽然,公平地说,我有点不确定在C#中静态是如何分配的-我只是假设它是以与C++类似的方式完成的]严格地说,这取决于代码的位置 如果代码位于常规函数/方法中,则只会影响堆栈。这对堆没有影响,因为还没有构造MyClass对象 假设MyClass是一个类(即引用类型),则每个声明都会在堆栈上保留足够的空间来保存对MyClass对象的引用 这两个声明稍有不同——第一个声明尚未初始化,因此在将其设置为某个值之前尝试访问myclass1将导致编译器错误。第二个是初始化的,因此不会出现编译器错误[尽管如果在将omiclass2的方法或属性设置为引用实际对象之前访问它,会出现运行时错误,例如,使用omiclass2=new MyClass();] 如果代码位于类声明中:
class Fred {
MyClass oMyClass1;
MyClass oMyClass2 = null;
}
然后,它将仅在Fred构造函数期间执行。在调用构造函数之前,堆上已经分配了空间(用于Fred对象,包括用于两个MyClass引用的空间)。这两行代码实际上没有任何效果,因为空格已经初始化为null
如果它位于结构声明内部,则效果类似,仅在堆栈(如果结构是本地的)或全局变量内存(如果结构是静态的)上。[虽然,公平地说,我有点不确定在C#中静态是如何分配的-我只是假设它是以与C++类似的方式完成的]
我的疑问是,上述两行将如何影响内存(堆栈和堆)
信息不足,有两种可能性:
正如我在一个现已删除的答案中所说的,不是类成员的值类型的实例并不总是存储在堆栈上。如果它们被lambda表达式或迭代器块捕获,则它们将存储在堆上。只有当它们是局部变量时,才会在堆栈上分配引用。如果他们是类成员,他们将在堆上。@Frédéric值得详细说明的是,如果他们被lambda捕获,他们将不再是“本地人”。它们将转换为对闭包类(即包装器对象)上属性的引用。闭包就在堆上。@chibacity,没错,“本地人”确实会被“提升”为成员。@chibacity-我想你只是在重复我在答案中写的东西。如果答案确实是错的,如果你能解释一下如何(我可能会学到一些东西!),我将不胜感激。但谢谢你对Frédéric的评论——我也是这么想的——lambda表达式、匿名代理、Linq等只是创建额外类的简写方式,就我而言,正如我在现已删除的答案中所说的,不是类成员的值类型的实例并不总是存储在堆栈上。如果它们被lambda表达式或迭代器块捕获,则它们将存储在堆上。只有当它们是局部变量时,才会在堆栈上分配引用。如果他们是类成员,他们将在堆上。@Frédéric值得详细说明的是,如果他们被lambda捕获,他们将不再是“本地人”。它们将转换为对闭包类(即a)上属性的引用