C# 结构值类型
我知道struct是一种值类型,这意味着它是在堆栈上定义的 但是我可以做一个A=新的A();(当然是我的结构)。它定义在堆上,只有引用变量在堆栈上 你能给我解释一下这个吗。你的代码(A=newa();)创建并初始化了结构。如果是局部变量,则在堆栈上初始化。如果它是一个成员变量,它将作为对象的一部分在堆上初始化。在C#/.NET中使用“new”并不一定意味着堆分配。这取决于上下文 但是我可以做一个A=新的A();(当然是我的结构)。它定义在堆上,只有引用变量在堆栈上 如果C# 结构值类型,c#,.net,C#,.net,我知道struct是一种值类型,这意味着它是在堆栈上定义的 但是我可以做一个A=新的A();(当然是我的结构)。它定义在堆上,只有引用变量在堆栈上 你能给我解释一下这个吗。你的代码(A=newa();)创建并初始化了结构。如果是局部变量,则在堆栈上初始化。如果它是一个成员变量,它将作为对象的一部分在堆上初始化。在C#/.NET中使用“new”并不一定意味着堆分配。这取决于上下文 但是我可以做一个A=新的A();(当然是我的结构)。它定义在堆上,只有引用变量在堆栈上 如果A如您所说是一种值类型,并
A
如您所说是一种值类型,并且A
是一种本地方法,那么它将被分配到堆栈上。除非在闭包中使用a
,否则它将作为编译器生成的类的堆分配对象的一部分进行分配
如果需要进一步分析,则必须发布
A
类型的定义以及定义此变量的整个方法。值类型有时存储在堆栈上。这是一个复杂的主题,通常变量(堆栈或堆)的确切存储与编程问题无关。值类型和引用类型之间的真正区别在于它们的行为(例如,值类型总是按值复制)
Eric Lippert详细介绍了该问题:
存储局部变量的地方是实现细节。
简单的局部变量通常存储在CPU寄存器和/或堆栈中 如果它们在闭包中被捕获,它们将被重写为堆分配对象中的成员。这是因为lamda可能比它创建的函数更长寿,因此它使用的变量也必须足够长 <>与C++中的C++不同,<强> >代码>新< /代码>并不意味着堆分配< /强>。这只是调用构造函数的语法 对值类型调用
new
,也没有新位置的语义。它的语义是在某处构造一个实例,然后将其复制到目标变量中
在我的心智模型中,有两种类型的存储:
您的示例属于第一类存储,因为您使用的是值类型。
a a=new a()
从概念上构造结构的新实例并将其复制到a中。当然,编译器可以对其进行优化。除非编译器能够保证在单线程代码中不能观察到这一点,否则它不会就地构造。对于成员变量,它通常不能。@Jason-是的,变量a可能是闭包的一部分,并由编译器提升。这条皱纹似乎超出了提问者的要求。正如我所说,它取决于上下文。使用new
实例化结构不会改变结构的存储方式或内存分配方式new
并不自动意味着它正在堆上分配内存。@Jim是对的。“new”不是指“在堆上分配”,而是指“适当地分配,然后运行适当的构造函数”。如何分配内存取决于运行时。